Browse Source

Merge tag 'spi-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi updates from Mark Brown:
 "As well as the usual driver updates and cleanups there's a few
  improvements to the core here:

   - The start of some improvements to factor out more of the SPI
     message loop into the core.  Right now this is just simplifying the
     code a bit but hopefully next time around we'll also have managed
     to roll out some noticable performance improvements which drivers
     can take advantage of.
   - Support for loading modules for ACPI enumerated SPI devices.
   - Managed registration for SPI controllers.
   - Helper for another common I/O pattern"

* tag 'spi-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (116 commits)
  spi/hspi: add device tree support
  spi: atmel: fix return value check in atmel_spi_probe()
  spi: spi-imx: only enable the clocks when we start to transfer a message
  spi/s3c64xx: Fix doubled clock disable on suspend
  spi/s3c64xx: Do not ignore return value of spi_master_resume/suspend
  spi: spi-mxs: Use u32 instead of uint32_t
  spi: spi-mxs: Don't set clock for each xfer
  spi: spi-mxs: Clean up setup_transfer function
  spi: spi-mxs: Remove check of spi mode bits
  spi: spi-mxs: Fix race in setup method
  spi: spi-mxs: Remove bogus setting of ssp clk rate field
  spi: spi-mxs: Remove full duplex check, spi core already does it
  spi: spi-mxs: Fix chip select control bits in DMA mode
  spi: spi-mxs: Fix extra CS pulses and read mode in multi-transfer messages
  spi: spi-mxs: Change flag arguments in txrx functions to bit flags
  spi: spi-mxs: Always clear INGORE_CRC, to keep CS asserted
  spi: spi-mxs: Remove mxs_spi_enable and mxs_spi_disable
  spi: spi-mxs: Always set LOCK_CS
  spi/s3c64xx: Add missing pm_runtime_put on setup fail
  spi/s3c64xx: Add missing pm_runtime_set_active() call in probe()
  ...
Linus Torvalds 11 years ago
parent
commit
f095ca6b31
62 changed files with 1267 additions and 701 deletions
  1. 7 0
      Documentation/devicetree/bindings/spi/sh-hspi.txt
  2. 3 0
      Documentation/driver-model/devres.txt
  3. 1 6
      drivers/hwmon/adt7310.c
  4. 3 2
      drivers/spi/Kconfig
  5. 1 1
      drivers/spi/spi-altera.c
  6. 1 1
      drivers/spi/spi-ath79.c
  7. 25 25
      drivers/spi/spi-atmel.c
  8. 3 2
      drivers/spi/spi-au1550.c
  9. 1 3
      drivers/spi/spi-bcm2835.c
  10. 1 5
      drivers/spi/spi-bcm63xx.c
  11. 15 14
      drivers/spi/spi-bfin-sport.c
  12. 1 2
      drivers/spi/spi-bfin-v3.c
  13. 26 22
      drivers/spi/spi-bfin5xx.c
  14. 18 7
      drivers/spi/spi-bitbang.c
  15. 7 8
      drivers/spi/spi-butterfly.c
  16. 2 5
      drivers/spi/spi-clps711x.c
  17. 6 7
      drivers/spi/spi-davinci.c
  18. 1 4
      drivers/spi/spi-dw-mmio.c
  19. 1 2
      drivers/spi/spi-dw-pci.c
  20. 2 2
      drivers/spi/spi-dw.c
  21. 4 8
      drivers/spi/spi-efm32.c
  22. 3 4
      drivers/spi/spi-ep93xx.c
  23. 1 1
      drivers/spi/spi-fsl-cpm.c
  24. 5 5
      drivers/spi/spi-fsl-dspi.c
  25. 2 2
      drivers/spi/spi-fsl-espi.c
  26. 3 3
      drivers/spi/spi-gpio.c
  27. 34 1
      drivers/spi/spi-imx.c
  28. 1 1
      drivers/spi/spi-lm70llp.c
  29. 1 3
      drivers/spi/spi-mpc512x-psc.c
  30. 2 2
      drivers/spi/spi-mpc52xx-psc.c
  31. 81 112
      drivers/spi/spi-mxs.c
  32. 1 2
      drivers/spi/spi-nuc900.c
  33. 1 1
      drivers/spi/spi-oc-tiny.c
  34. 1 3
      drivers/spi/spi-octeon.c
  35. 1 3
      drivers/spi/spi-omap-100k.c
  36. 3 2
      drivers/spi/spi-omap-uwire.c
  37. 12 7
      drivers/spi/spi-omap2-mcspi.c
  38. 4 6
      drivers/spi/spi-orion.c
  39. 3 7
      drivers/spi/spi-pl022.c
  40. 2 1
      drivers/spi/spi-ppc4xx.c
  41. 17 24
      drivers/spi/spi-pxa2xx.c
  42. 231 39
      drivers/spi/spi-rspi.c
  43. 2 2
      drivers/spi/spi-s3c24xx.c
  44. 126 134
      drivers/spi/spi-s3c64xx.c
  45. 10 3
      drivers/spi/spi-sh-hspi.c
  46. 1 1
      drivers/spi/spi-sh-sci.c
  47. 1 1
      drivers/spi/spi-sirf.c
  48. 70 20
      drivers/spi/spi-tegra114.c
  49. 2 3
      drivers/spi/spi-tegra20-sflash.c
  50. 69 75
      drivers/spi/spi-tegra20-slink.c
  51. 9 37
      drivers/spi/spi-ti-qspi.c
  52. 9 8
      drivers/spi/spi-topcliff-pch.c
  53. 5 6
      drivers/spi/spi-txx9.c
  54. 1 1
      drivers/spi/spi-xilinx.c
  55. 201 43
      drivers/spi/spi.c
  56. 3 4
      drivers/spi/spidev.c
  57. 1 2
      drivers/staging/iio/meter/ade7753.c
  58. 1 2
      drivers/staging/iio/meter/ade7754.c
  59. 1 2
      drivers/staging/iio/meter/ade7759.c
  60. 2 0
      include/linux/spi/rspi.h
  61. 59 2
      include/linux/spi/spi.h
  62. 156 0
      include/trace/events/spi.h

+ 7 - 0
Documentation/devicetree/bindings/spi/sh-hspi.txt

@@ -0,0 +1,7 @@
+Renesas HSPI.
+
+Required properties:
+- compatible : 	"renesas,hspi"
+- reg : Offset and length of the register set for the device
+- interrupts : interrupt line used by HSPI
+

+ 3 - 0
Documentation/driver-model/devres.txt

@@ -303,3 +303,6 @@ PHY
 
 
 SLAVE DMA ENGINE
 SLAVE DMA ENGINE
   devm_acpi_dma_controller_register()
   devm_acpi_dma_controller_register()
+
+SPI
+  devm_spi_register_master()

+ 1 - 6
drivers/hwmon/adt7310.c

@@ -42,13 +42,8 @@ static const u8 adt7310_reg_table[] = {
 static int adt7310_spi_read_word(struct device *dev, u8 reg)
 static int adt7310_spi_read_word(struct device *dev, u8 reg)
 {
 {
 	struct spi_device *spi = to_spi_device(dev);
 	struct spi_device *spi = to_spi_device(dev);
-	int ret;
 
 
-	ret = spi_w8r16(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
-	if (ret < 0)
-		return ret;
-
-	return be16_to_cpu((__force __be16)ret);
+	return spi_w8r16be(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
 }
 }
 
 
 static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data)
 static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data)

+ 3 - 2
drivers/spi/Kconfig

@@ -264,6 +264,7 @@ config SPI_FSL_SPI
 config SPI_FSL_DSPI
 config SPI_FSL_DSPI
 	tristate "Freescale DSPI controller"
 	tristate "Freescale DSPI controller"
 	select SPI_BITBANG
 	select SPI_BITBANG
+	depends on SOC_VF610 || COMPILE_TEST
 	help
 	help
 	  This enables support for the Freescale DSPI controller in master
 	  This enables support for the Freescale DSPI controller in master
 	  mode. VF610 platform uses the controller.
 	  mode. VF610 platform uses the controller.
@@ -369,7 +370,7 @@ config SPI_PXA2XX_PCI
 
 
 config SPI_RSPI
 config SPI_RSPI
 	tristate "Renesas RSPI controller"
 	tristate "Renesas RSPI controller"
-	depends on SUPERH && SH_DMAE_BASE
+	depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE
 	help
 	help
 	  SPI driver for Renesas RSPI blocks.
 	  SPI driver for Renesas RSPI blocks.
 
 
@@ -393,7 +394,7 @@ config SPI_S3C24XX_FIQ
 
 
 config SPI_S3C64XX
 config SPI_S3C64XX
 	tristate "Samsung S3C64XX series type SPI"
 	tristate "Samsung S3C64XX series type SPI"
-	depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS)
+	depends on PLAT_SAMSUNG
 	select S3C64XX_DMA if ARCH_S3C64XX
 	select S3C64XX_DMA if ARCH_S3C64XX
 	help
 	help
 	  SPI driver for Samsung S3C64XX and newer SoCs.
 	  SPI driver for Samsung S3C64XX and newer SoCs.

+ 1 - 1
drivers/spi/spi-altera.c

@@ -219,7 +219,7 @@ static int altera_spi_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, hw);
 	platform_set_drvdata(pdev, hw);
 
 
 	/* setup the state for the bitbang driver */
 	/* setup the state for the bitbang driver */
-	hw->bitbang.master = spi_master_get(master);
+	hw->bitbang.master = master;
 	if (!hw->bitbang.master)
 	if (!hw->bitbang.master)
 		return err;
 		return err;
 	hw->bitbang.chipselect = altera_spi_chipsel;
 	hw->bitbang.chipselect = altera_spi_chipsel;

+ 1 - 1
drivers/spi/spi-ath79.c

@@ -231,7 +231,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
 		master->num_chipselect = pdata->num_chipselect;
 		master->num_chipselect = pdata->num_chipselect;
 	}
 	}
 
 
-	sp->bitbang.master = spi_master_get(master);
+	sp->bitbang.master = master;
 	sp->bitbang.chipselect = ath79_spi_chipselect;
 	sp->bitbang.chipselect = ath79_spi_chipselect;
 	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
 	sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
 	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
 	sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;

+ 25 - 25
drivers/spi/spi-atmel.c

@@ -170,18 +170,18 @@
 /* Bit manipulation macros */
 /* Bit manipulation macros */
 #define SPI_BIT(name) \
 #define SPI_BIT(name) \
 	(1 << SPI_##name##_OFFSET)
 	(1 << SPI_##name##_OFFSET)
-#define SPI_BF(name,value) \
+#define SPI_BF(name, value) \
 	(((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET)
 	(((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET)
-#define SPI_BFEXT(name,value) \
+#define SPI_BFEXT(name, value) \
 	(((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1))
 	(((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1))
-#define SPI_BFINS(name,value,old) \
-	( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
-	  | SPI_BF(name,value))
+#define SPI_BFINS(name, value, old) \
+	(((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
+	  | SPI_BF(name, value))
 
 
 /* Register access macros */
 /* Register access macros */
-#define spi_readl(port,reg) \
+#define spi_readl(port, reg) \
 	__raw_readl((port)->regs + SPI_##reg)
 	__raw_readl((port)->regs + SPI_##reg)
-#define spi_writel(port,reg,value) \
+#define spi_writel(port, reg, value) \
 	__raw_writel((value), (port)->regs + SPI_##reg)
 	__raw_writel((value), (port)->regs + SPI_##reg)
 
 
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
 /* use PIO for small transfers, avoiding DMA setup/teardown overhead and
@@ -1401,8 +1401,8 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
 			asd = spi->controller_state;
 			asd = spi->controller_state;
 			bits = (asd->csr >> 4) & 0xf;
 			bits = (asd->csr >> 4) & 0xf;
 			if (bits != xfer->bits_per_word - 8) {
 			if (bits != xfer->bits_per_word - 8) {
-				dev_dbg(&spi->dev, "you can't yet change "
-					 "bits_per_word in transfers\n");
+				dev_dbg(&spi->dev,
+					"you can't yet change bits_per_word in transfers\n");
 				return -ENOPROTOOPT;
 				return -ENOPROTOOPT;
 			}
 			}
 		}
 		}
@@ -1516,7 +1516,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
 
 
 	/* setup spi core then atmel-specific driver state */
 	/* setup spi core then atmel-specific driver state */
 	ret = -ENOMEM;
 	ret = -ENOMEM;
-	master = spi_alloc_master(&pdev->dev, sizeof *as);
+	master = spi_alloc_master(&pdev->dev, sizeof(*as));
 	if (!master)
 	if (!master)
 		goto out_free;
 		goto out_free;
 
 
@@ -1546,9 +1546,11 @@ static int atmel_spi_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&as->queue);
 	INIT_LIST_HEAD(&as->queue);
 
 
 	as->pdev = pdev;
 	as->pdev = pdev;
-	as->regs = ioremap(regs->start, resource_size(regs));
-	if (!as->regs)
+	as->regs = devm_ioremap_resource(&pdev->dev, regs);
+	if (IS_ERR(as->regs)) {
+		ret = PTR_ERR(as->regs);
 		goto out_free_buffer;
 		goto out_free_buffer;
+	}
 	as->phybase = regs->start;
 	as->phybase = regs->start;
 	as->irq = irq;
 	as->irq = irq;
 	as->clk = clk;
 	as->clk = clk;
@@ -1617,7 +1619,6 @@ out_free_dma:
 out_free_irq:
 out_free_irq:
 	free_irq(irq, master);
 	free_irq(irq, master);
 out_unmap_regs:
 out_unmap_regs:
-	iounmap(as->regs);
 out_free_buffer:
 out_free_buffer:
 	if (!as->use_pdc)
 	if (!as->use_pdc)
 		tasklet_kill(&as->tasklet);
 		tasklet_kill(&as->tasklet);
@@ -1669,36 +1670,36 @@ static int atmel_spi_remove(struct platform_device *pdev)
 	clk_disable_unprepare(as->clk);
 	clk_disable_unprepare(as->clk);
 	clk_put(as->clk);
 	clk_put(as->clk);
 	free_irq(as->irq, master);
 	free_irq(as->irq, master);
-	iounmap(as->regs);
 
 
 	spi_unregister_master(master);
 	spi_unregister_master(master);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef	CONFIG_PM
-
-static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
+#ifdef CONFIG_PM_SLEEP
+static int atmel_spi_suspend(struct device *dev)
 {
 {
-	struct spi_master	*master = platform_get_drvdata(pdev);
+	struct spi_master	*master = dev_get_drvdata(dev);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 
 
 	clk_disable_unprepare(as->clk);
 	clk_disable_unprepare(as->clk);
 	return 0;
 	return 0;
 }
 }
 
 
-static int atmel_spi_resume(struct platform_device *pdev)
+static int atmel_spi_resume(struct device *dev)
 {
 {
-	struct spi_master	*master = platform_get_drvdata(pdev);
+	struct spi_master	*master = dev_get_drvdata(dev);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 
 
-	return clk_prepare_enable(as->clk);
+	clk_prepare_enable(as->clk);
 	return 0;
 	return 0;
 }
 }
 
 
+static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume);
+
+#define ATMEL_SPI_PM_OPS	(&atmel_spi_pm_ops)
 #else
 #else
-#define	atmel_spi_suspend	NULL
-#define	atmel_spi_resume	NULL
+#define ATMEL_SPI_PM_OPS	NULL
 #endif
 #endif
 
 
 #if defined(CONFIG_OF)
 #if defined(CONFIG_OF)
@@ -1714,10 +1715,9 @@ static struct platform_driver atmel_spi_driver = {
 	.driver		= {
 	.driver		= {
 		.name	= "atmel_spi",
 		.name	= "atmel_spi",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
+		.pm	= ATMEL_SPI_PM_OPS,
 		.of_match_table	= of_match_ptr(atmel_spi_dt_ids),
 		.of_match_table	= of_match_ptr(atmel_spi_dt_ids),
 	},
 	},
-	.suspend	= atmel_spi_suspend,
-	.resume		= atmel_spi_resume,
 	.probe		= atmel_spi_probe,
 	.probe		= atmel_spi_probe,
 	.remove		= atmel_spi_remove,
 	.remove		= atmel_spi_remove,
 };
 };

+ 3 - 2
drivers/spi/spi-au1550.c

@@ -775,7 +775,7 @@ static int au1550_spi_probe(struct platform_device *pdev)
 
 
 	hw = spi_master_get_devdata(master);
 	hw = spi_master_get_devdata(master);
 
 
-	hw->master = spi_master_get(master);
+	hw->master = master;
 	hw->pdata = dev_get_platdata(&pdev->dev);
 	hw->pdata = dev_get_platdata(&pdev->dev);
 	hw->dev = &pdev->dev;
 	hw->dev = &pdev->dev;
 
 
@@ -985,6 +985,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
 MODULE_ALIAS("platform:au1550-spi");
 MODULE_ALIAS("platform:au1550-spi");
 
 
 static struct platform_driver au1550_spi_drv = {
 static struct platform_driver au1550_spi_drv = {
+	.probe = au1550_spi_probe,
 	.remove = au1550_spi_remove,
 	.remove = au1550_spi_remove,
 	.driver = {
 	.driver = {
 		.name = "au1550-spi",
 		.name = "au1550-spi",
@@ -1004,7 +1005,7 @@ static int __init au1550_spi_init(void)
 			printk(KERN_ERR "au1550-spi: cannot add memory"
 			printk(KERN_ERR "au1550-spi: cannot add memory"
 					"dbdma device\n");
 					"dbdma device\n");
 	}
 	}
-	return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
+	return platform_driver_register(&au1550_spi_drv);
 }
 }
 module_init(au1550_spi_init);
 module_init(au1550_spi_init);
 
 

+ 1 - 3
drivers/spi/spi-bcm2835.c

@@ -358,7 +358,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
 	bcm2835_wr(bs, BCM2835_SPI_CS,
 	bcm2835_wr(bs, BCM2835_SPI_CS,
 		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 
 
-	err = spi_register_master(master);
+	err = devm_spi_register_master(&pdev->dev, master);
 	if (err) {
 	if (err) {
 		dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
 		dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
 		goto out_free_irq;
 		goto out_free_irq;
@@ -381,14 +381,12 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
 	struct bcm2835_spi *bs = spi_master_get_devdata(master);
 	struct bcm2835_spi *bs = spi_master_get_devdata(master);
 
 
 	free_irq(bs->irq, master);
 	free_irq(bs->irq, master);
-	spi_unregister_master(master);
 
 
 	/* Clear FIFOs, and disable the HW block */
 	/* Clear FIFOs, and disable the HW block */
 	bcm2835_wr(bs, BCM2835_SPI_CS,
 	bcm2835_wr(bs, BCM2835_SPI_CS,
 		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 		   BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
 
 
 	clk_disable_unprepare(bs->clk);
 	clk_disable_unprepare(bs->clk);
-	spi_master_put(master);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 5
drivers/spi/spi-bcm63xx.c

@@ -412,7 +412,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
 	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
 
 
 	/* register and we are done */
 	/* register and we are done */
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(dev, master);
 	if (ret) {
 	if (ret) {
 		dev_err(dev, "spi register failed\n");
 		dev_err(dev, "spi register failed\n");
 		goto out_clk_disable;
 		goto out_clk_disable;
@@ -438,8 +438,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
 	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
 
 
-	spi_unregister_master(master);
-
 	/* reset spi block */
 	/* reset spi block */
 	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 	bcm_spi_writeb(bs, 0, SPI_INT_MASK);
 
 
@@ -447,8 +445,6 @@ static int bcm63xx_spi_remove(struct platform_device *pdev)
 	clk_disable_unprepare(bs->clk);
 	clk_disable_unprepare(bs->clk);
 	clk_put(bs->clk);
 	clk_put(bs->clk);
 
 
-	spi_master_put(master);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 15 - 14
drivers/spi/spi-bfin-sport.c

@@ -592,7 +592,7 @@ bfin_sport_spi_setup(struct spi_device *spi)
 			 */
 			 */
 			if (chip_info->ctl_reg || chip_info->enable_dma) {
 			if (chip_info->ctl_reg || chip_info->enable_dma) {
 				ret = -EINVAL;
 				ret = -EINVAL;
-				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields");
+				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields\n");
 				goto error;
 				goto error;
 			}
 			}
 			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
 			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
@@ -879,11 +879,10 @@ static int bfin_sport_spi_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
-static int
-bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int bfin_sport_spi_suspend(struct device *dev)
 {
 {
-	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
 	int status;
 	int status;
 
 
 	status = bfin_sport_spi_stop_queue(drv_data);
 	status = bfin_sport_spi_stop_queue(drv_data);
@@ -896,10 +895,9 @@ bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
 	return status;
 	return status;
 }
 }
 
 
-static int
-bfin_sport_spi_resume(struct platform_device *pdev)
+static int bfin_sport_spi_resume(struct device *dev)
 {
 {
-	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	struct bfin_sport_spi_master_data *drv_data = dev_get_drvdata(dev);
 	int status;
 	int status;
 
 
 	/* Enable the SPI interface */
 	/* Enable the SPI interface */
@@ -912,19 +910,22 @@ bfin_sport_spi_resume(struct platform_device *pdev)
 
 
 	return status;
 	return status;
 }
 }
+
+static SIMPLE_DEV_PM_OPS(bfin_sport_spi_pm_ops, bfin_sport_spi_suspend,
+			bfin_sport_spi_resume);
+
+#define BFIN_SPORT_SPI_PM_OPS		(&bfin_sport_spi_pm_ops)
 #else
 #else
-# define bfin_sport_spi_suspend NULL
-# define bfin_sport_spi_resume  NULL
+#define BFIN_SPORT_SPI_PM_OPS		NULL
 #endif
 #endif
 
 
 static struct platform_driver bfin_sport_spi_driver = {
 static struct platform_driver bfin_sport_spi_driver = {
 	.driver	= {
 	.driver	= {
-		.name = DRV_NAME,
-		.owner = THIS_MODULE,
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= BFIN_SPORT_SPI_PM_OPS,
 	},
 	},
 	.probe   = bfin_sport_spi_probe,
 	.probe   = bfin_sport_spi_probe,
 	.remove  = bfin_sport_spi_remove,
 	.remove  = bfin_sport_spi_remove,
-	.suspend = bfin_sport_spi_suspend,
-	.resume  = bfin_sport_spi_resume,
 };
 };
 module_platform_driver(bfin_sport_spi_driver);
 module_platform_driver(bfin_sport_spi_driver);

+ 1 - 2
drivers/spi/spi-bfin-v3.c

@@ -867,7 +867,7 @@ static int bfin_spi_probe(struct platform_device *pdev)
 	tasklet_init(&drv_data->pump_transfers,
 	tasklet_init(&drv_data->pump_transfers,
 			bfin_spi_pump_transfers, (unsigned long)drv_data);
 			bfin_spi_pump_transfers, (unsigned long)drv_data);
 	/* register with the SPI framework */
 	/* register with the SPI framework */
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(dev, master);
 	if (ret) {
 	if (ret) {
 		dev_err(dev, "can not  register spi master\n");
 		dev_err(dev, "can not  register spi master\n");
 		goto err_free_peripheral;
 		goto err_free_peripheral;
@@ -898,7 +898,6 @@ static int bfin_spi_remove(struct platform_device *pdev)
 	free_dma(drv_data->rx_dma);
 	free_dma(drv_data->rx_dma);
 	free_dma(drv_data->tx_dma);
 	free_dma(drv_data->tx_dma);
 
 
-	spi_unregister_master(drv_data->master);
 	return 0;
 	return 0;
 }
 }
 
 

+ 26 - 22
drivers/spi/spi-bfin5xx.c

@@ -524,7 +524,7 @@ static irqreturn_t bfin_spi_dma_irq_handler(int irq, void *dev_id)
 	timeout = jiffies + HZ;
 	timeout = jiffies + HZ;
 	while (!(bfin_read(&drv_data->regs->stat) & BIT_STAT_SPIF))
 	while (!(bfin_read(&drv_data->regs->stat) & BIT_STAT_SPIF))
 		if (!time_before(jiffies, timeout)) {
 		if (!time_before(jiffies, timeout)) {
-			dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF");
+			dev_warn(&drv_data->pdev->dev, "timeout waiting for SPIF\n");
 			break;
 			break;
 		} else
 		} else
 			cpu_relax();
 			cpu_relax();
@@ -913,8 +913,9 @@ static void bfin_spi_pump_messages(struct work_struct *work)
 	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
 	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
 					    struct spi_transfer, transfer_list);
 					    struct spi_transfer, transfer_list);
 
 
-	dev_dbg(&drv_data->pdev->dev, "got a message to pump, "
-		"state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
+	dev_dbg(&drv_data->pdev->dev,
+		"got a message to pump, state is set to: baud "
+		"%d, flag 0x%x, ctl 0x%x\n",
 		drv_data->cur_chip->baud, drv_data->cur_chip->flag,
 		drv_data->cur_chip->baud, drv_data->cur_chip->flag,
 		drv_data->cur_chip->ctl_reg);
 		drv_data->cur_chip->ctl_reg);
 
 
@@ -1013,8 +1014,8 @@ static int bfin_spi_setup(struct spi_device *spi)
 		 * but let's assume (for now) they do.
 		 * but let's assume (for now) they do.
 		 */
 		 */
 		if (chip_info->ctl_reg & ~bfin_ctl_reg) {
 		if (chip_info->ctl_reg & ~bfin_ctl_reg) {
-			dev_err(&spi->dev, "do not set bits in ctl_reg "
-				"that the SPI framework manages\n");
+			dev_err(&spi->dev,
+				"do not set bits in ctl_reg that the SPI framework manages\n");
 			goto error;
 			goto error;
 		}
 		}
 		chip->enable_dma = chip_info->enable_dma != 0
 		chip->enable_dma = chip_info->enable_dma != 0
@@ -1050,17 +1051,17 @@ static int bfin_spi_setup(struct spi_device *spi)
 	chip->chip_select_num = spi->chip_select;
 	chip->chip_select_num = spi->chip_select;
 	if (chip->chip_select_num < MAX_CTRL_CS) {
 	if (chip->chip_select_num < MAX_CTRL_CS) {
 		if (!(spi->mode & SPI_CPHA))
 		if (!(spi->mode & SPI_CPHA))
-			dev_warn(&spi->dev, "Warning: SPI CPHA not set:"
-				" Slave Select not under software control!\n"
-				" See Documentation/blackfin/bfin-spi-notes.txt");
+			dev_warn(&spi->dev,
+				"Warning: SPI CPHA not set: Slave Select not under software control!\n"
+				"See Documentation/blackfin/bfin-spi-notes.txt\n");
 
 
 		chip->flag = (1 << spi->chip_select) << 8;
 		chip->flag = (1 << spi->chip_select) << 8;
 	} else
 	} else
 		chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS;
 		chip->cs_gpio = chip->chip_select_num - MAX_CTRL_CS;
 
 
 	if (chip->enable_dma && chip->pio_interrupt) {
 	if (chip->enable_dma && chip->pio_interrupt) {
-		dev_err(&spi->dev, "enable_dma is set, "
-				"do not set pio_interrupt\n");
+		dev_err(&spi->dev,
+			"enable_dma is set, do not set pio_interrupt\n");
 		goto error;
 		goto error;
 	}
 	}
 	/*
 	/*
@@ -1410,10 +1411,10 @@ static int bfin_spi_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
-static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int bfin_spi_suspend(struct device *dev)
 {
 {
-	struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);
 	int status = 0;
 	int status = 0;
 
 
 	status = bfin_spi_stop_queue(drv_data);
 	status = bfin_spi_stop_queue(drv_data);
@@ -1432,9 +1433,9 @@ static int bfin_spi_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 	return 0;
 }
 }
 
 
-static int bfin_spi_resume(struct platform_device *pdev)
+static int bfin_spi_resume(struct device *dev)
 {
 {
-	struct bfin_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	struct bfin_spi_master_data *drv_data = dev_get_drvdata(dev);
 	int status = 0;
 	int status = 0;
 
 
 	bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg);
 	bfin_write(&drv_data->regs->ctl, drv_data->ctrl_reg);
@@ -1443,31 +1444,34 @@ static int bfin_spi_resume(struct platform_device *pdev)
 	/* Start the queue running */
 	/* Start the queue running */
 	status = bfin_spi_start_queue(drv_data);
 	status = bfin_spi_start_queue(drv_data);
 	if (status != 0) {
 	if (status != 0) {
-		dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
+		dev_err(dev, "problem starting queue (%d)\n", status);
 		return status;
 		return status;
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
+
+static SIMPLE_DEV_PM_OPS(bfin_spi_pm_ops, bfin_spi_suspend, bfin_spi_resume);
+
+#define BFIN_SPI_PM_OPS		(&bfin_spi_pm_ops)
 #else
 #else
-#define bfin_spi_suspend NULL
-#define bfin_spi_resume NULL
-#endif				/* CONFIG_PM */
+#define BFIN_SPI_PM_OPS		NULL
+#endif
 
 
 MODULE_ALIAS("platform:bfin-spi");
 MODULE_ALIAS("platform:bfin-spi");
 static struct platform_driver bfin_spi_driver = {
 static struct platform_driver bfin_spi_driver = {
 	.driver	= {
 	.driver	= {
 		.name	= DRV_NAME,
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
+		.pm	= BFIN_SPI_PM_OPS,
 	},
 	},
-	.suspend	= bfin_spi_suspend,
-	.resume		= bfin_spi_resume,
+	.probe		= bfin_spi_probe,
 	.remove		= bfin_spi_remove,
 	.remove		= bfin_spi_remove,
 };
 };
 
 
 static int __init bfin_spi_init(void)
 static int __init bfin_spi_init(void)
 {
 {
-	return platform_driver_probe(&bfin_spi_driver, bfin_spi_probe);
+	return platform_driver_register(&bfin_spi_driver);
 }
 }
 subsys_initcall(bfin_spi_init);
 subsys_initcall(bfin_spi_init);
 
 

+ 18 - 7
drivers/spi/spi-bitbang.c

@@ -191,7 +191,7 @@ int spi_bitbang_setup(struct spi_device *spi)
 	bitbang = spi_master_get_devdata(spi->master);
 	bitbang = spi_master_get_devdata(spi->master);
 
 
 	if (!cs) {
 	if (!cs) {
-		cs = kzalloc(sizeof *cs, GFP_KERNEL);
+		cs = kzalloc(sizeof(*cs), GFP_KERNEL);
 		if (!cs)
 		if (!cs)
 			return -ENOMEM;
 			return -ENOMEM;
 		spi->controller_state = cs;
 		spi->controller_state = cs;
@@ -258,7 +258,7 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
 
 
 static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 {
 {
-	struct spi_bitbang 	*bitbang;
+	struct spi_bitbang	*bitbang;
 	unsigned long		flags;
 	unsigned long		flags;
 
 
 	bitbang = spi_master_get_devdata(spi);
 	bitbang = spi_master_get_devdata(spi);
@@ -273,7 +273,7 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 static int spi_bitbang_transfer_one(struct spi_master *master,
 static int spi_bitbang_transfer_one(struct spi_master *master,
 				    struct spi_message *m)
 				    struct spi_message *m)
 {
 {
-	struct spi_bitbang 	*bitbang;
+	struct spi_bitbang	*bitbang;
 	unsigned		nsecs;
 	unsigned		nsecs;
 	struct spi_transfer	*t = NULL;
 	struct spi_transfer	*t = NULL;
 	unsigned		cs_change;
 	unsigned		cs_change;
@@ -292,7 +292,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 	cs_change = 1;
 	cs_change = 1;
 	status = 0;
 	status = 0;
 
 
-	list_for_each_entry (t, &m->transfers, transfer_list) {
+	list_for_each_entry(t, &m->transfers, transfer_list) {
 
 
 		/* override speed or wordsize? */
 		/* override speed or wordsize? */
 		if (t->speed_hz || t->bits_per_word)
 		if (t->speed_hz || t->bits_per_word)
@@ -349,7 +349,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 		if (t->delay_usecs)
 		if (t->delay_usecs)
 			udelay(t->delay_usecs);
 			udelay(t->delay_usecs);
 
 
-		if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) {
+		if (cs_change &&
+		    !list_is_last(&t->transfer_list, &m->transfers)) {
 			/* sometimes a short mid-message deselect of the chip
 			/* sometimes a short mid-message deselect of the chip
 			 * may be needed to terminate a mode or command
 			 * may be needed to terminate a mode or command
 			 */
 			 */
@@ -378,7 +379,7 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
 
 static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 {
 {
-	struct spi_bitbang 	*bitbang;
+	struct spi_bitbang	*bitbang;
 	unsigned long		flags;
 	unsigned long		flags;
 
 
 	bitbang = spi_master_get_devdata(spi);
 	bitbang = spi_master_get_devdata(spi);
@@ -414,10 +415,16 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
  * This routine registers the spi_master, which will process requests in a
  * This routine registers the spi_master, which will process requests in a
  * dedicated task, keeping IRQs unblocked most of the time.  To stop
  * dedicated task, keeping IRQs unblocked most of the time.  To stop
  * processing those requests, call spi_bitbang_stop().
  * processing those requests, call spi_bitbang_stop().
+ *
+ * On success, this routine will take a reference to master. The caller is
+ * responsible for calling spi_bitbang_stop() to decrement the reference and
+ * spi_master_put() as counterpart of spi_alloc_master() to prevent a memory
+ * leak.
  */
  */
 int spi_bitbang_start(struct spi_bitbang *bitbang)
 int spi_bitbang_start(struct spi_bitbang *bitbang)
 {
 {
 	struct spi_master *master = bitbang->master;
 	struct spi_master *master = bitbang->master;
+	int ret;
 
 
 	if (!master || !bitbang->chipselect)
 	if (!master || !bitbang->chipselect)
 		return -EINVAL;
 		return -EINVAL;
@@ -449,7 +456,11 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	/* driver may get busy before register() returns, especially
 	/* driver may get busy before register() returns, especially
 	 * if someone registered boardinfo for devices
 	 * if someone registered boardinfo for devices
 	 */
 	 */
-	return spi_register_master(master);
+	ret = spi_register_master(spi_master_get(master));
+	if (ret)
+		spi_master_put(master);
+
+	return 0;
 }
 }
 EXPORT_SYMBOL_GPL(spi_bitbang_start);
 EXPORT_SYMBOL_GPL(spi_bitbang_start);
 
 

+ 7 - 8
drivers/spi/spi-butterfly.c

@@ -147,8 +147,8 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
 
 
 /* we only needed to implement one mode here, and choose SPI_MODE_0 */
 /* we only needed to implement one mode here, and choose SPI_MODE_0 */
 
 
-#define	spidelay(X)	do{}while(0)
-//#define	spidelay	ndelay
+#define spidelay(X)	do { } while (0)
+/* #define spidelay	ndelay */
 
 
 #include "spi-bitbang-txrx.h"
 #include "spi-bitbang-txrx.h"
 
 
@@ -171,15 +171,15 @@ static struct mtd_partition partitions[] = { {
 	/* sector 0 = 8 pages * 264 bytes/page (1 block)
 	/* sector 0 = 8 pages * 264 bytes/page (1 block)
 	 * sector 1 = 248 pages * 264 bytes/page
 	 * sector 1 = 248 pages * 264 bytes/page
 	 */
 	 */
-	.name		= "bookkeeping",	// 66 KB
+	.name		= "bookkeeping",	/* 66 KB */
 	.offset		= 0,
 	.offset		= 0,
 	.size		= (8 + 248) * 264,
 	.size		= (8 + 248) * 264,
-//	.mask_flags	= MTD_WRITEABLE,
+	/* .mask_flags	= MTD_WRITEABLE, */
 }, {
 }, {
 	/* sector 2 = 256 pages * 264 bytes/page
 	/* sector 2 = 256 pages * 264 bytes/page
 	 * sectors 3-5 = 512 pages * 264 bytes/page
 	 * sectors 3-5 = 512 pages * 264 bytes/page
 	 */
 	 */
-	.name		= "filesystem",		// 462 KB
+	.name		= "filesystem",		/* 462 KB */
 	.offset		= MTDPART_OFS_APPEND,
 	.offset		= MTDPART_OFS_APPEND,
 	.size		= MTDPART_SIZ_FULL,
 	.size		= MTDPART_SIZ_FULL,
 } };
 } };
@@ -209,7 +209,7 @@ static void butterfly_attach(struct parport *p)
 	 * and no way to be selective about what it binds to.
 	 * and no way to be selective about what it binds to.
 	 */
 	 */
 
 
-	master = spi_alloc_master(dev, sizeof *pp);
+	master = spi_alloc_master(dev, sizeof(*pp));
 	if (!master) {
 	if (!master) {
 		status = -ENOMEM;
 		status = -ENOMEM;
 		goto done;
 		goto done;
@@ -225,7 +225,7 @@ static void butterfly_attach(struct parport *p)
 	master->bus_num = 42;
 	master->bus_num = 42;
 	master->num_chipselect = 2;
 	master->num_chipselect = 2;
 
 
-	pp->bitbang.master = spi_master_get(master);
+	pp->bitbang.master = master;
 	pp->bitbang.chipselect = butterfly_chipselect;
 	pp->bitbang.chipselect = butterfly_chipselect;
 	pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
 	pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0;
 
 
@@ -289,7 +289,6 @@ static void butterfly_attach(struct parport *p)
 		pr_debug("%s: dataflash at %s\n", p->name,
 		pr_debug("%s: dataflash at %s\n", p->name,
 				dev_name(&pp->dataflash->dev));
 				dev_name(&pp->dataflash->dev));
 
 
-	// dev_info(_what?_, ...)
 	pr_info("%s: AVR Butterfly\n", p->name);
 	pr_info("%s: AVR Butterfly\n", p->name);
 	butterfly = pp;
 	butterfly = pp;
 	return;
 	return;

+ 2 - 5
drivers/spi/spi-clps711x.c

@@ -226,10 +226,10 @@ static int spi_clps711x_probe(struct platform_device *pdev)
 			       dev_name(&pdev->dev), hw);
 			       dev_name(&pdev->dev), hw);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "Can't request IRQ\n");
 		dev_err(&pdev->dev, "Can't request IRQ\n");
-		goto clk_out;
+		goto err_out;
 	}
 	}
 
 
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (!ret) {
 	if (!ret) {
 		dev_info(&pdev->dev,
 		dev_info(&pdev->dev,
 			 "SPI bus driver initialized. Master clock %u Hz\n",
 			 "SPI bus driver initialized. Master clock %u Hz\n",
@@ -239,7 +239,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
 
 
 	dev_err(&pdev->dev, "Failed to register master\n");
 	dev_err(&pdev->dev, "Failed to register master\n");
 
 
-clk_out:
 err_out:
 err_out:
 	while (--i >= 0)
 	while (--i >= 0)
 		if (gpio_is_valid(hw->chipselect[i]))
 		if (gpio_is_valid(hw->chipselect[i]))
@@ -260,8 +259,6 @@ static int spi_clps711x_remove(struct platform_device *pdev)
 		if (gpio_is_valid(hw->chipselect[i]))
 		if (gpio_is_valid(hw->chipselect[i]))
 			gpio_free(hw->chipselect[i]);
 			gpio_free(hw->chipselect[i]);
 
 
-	spi_unregister_master(master);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 6 - 7
drivers/spi/spi-davinci.c

@@ -279,7 +279,8 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
 	struct davinci_spi *dspi;
 	struct davinci_spi *dspi;
 	struct davinci_spi_config *spicfg;
 	struct davinci_spi_config *spicfg;
 	u8 bits_per_word = 0;
 	u8 bits_per_word = 0;
-	u32 hz = 0, spifmt = 0, prescale = 0;
+	u32 hz = 0, spifmt = 0;
+	int prescale;
 
 
 	dspi = spi_master_get_devdata(spi->master);
 	dspi = spi_master_get_devdata(spi->master);
 	spicfg = (struct davinci_spi_config *)spi->controller_data;
 	spicfg = (struct davinci_spi_config *)spi->controller_data;
@@ -916,7 +917,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
 	if (ret)
 	if (ret)
 		goto unmap_io;
 		goto unmap_io;
 
 
-	dspi->bitbang.master = spi_master_get(master);
+	dspi->bitbang.master = master;
 	if (dspi->bitbang.master == NULL) {
 	if (dspi->bitbang.master == NULL) {
 		ret = -ENODEV;
 		ret = -ENODEV;
 		goto irq_free;
 		goto irq_free;
@@ -925,7 +926,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
 	dspi->clk = clk_get(&pdev->dev, NULL);
 	dspi->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dspi->clk)) {
 	if (IS_ERR(dspi->clk)) {
 		ret = -ENODEV;
 		ret = -ENODEV;
-		goto put_master;
+		goto irq_free;
 	}
 	}
 	clk_prepare_enable(dspi->clk);
 	clk_prepare_enable(dspi->clk);
 
 
@@ -1015,8 +1016,6 @@ free_dma:
 free_clk:
 free_clk:
 	clk_disable_unprepare(dspi->clk);
 	clk_disable_unprepare(dspi->clk);
 	clk_put(dspi->clk);
 	clk_put(dspi->clk);
-put_master:
-	spi_master_put(master);
 irq_free:
 irq_free:
 	free_irq(dspi->irq, dspi);
 	free_irq(dspi->irq, dspi);
 unmap_io:
 unmap_io:
@@ -1024,7 +1023,7 @@ unmap_io:
 release_region:
 release_region:
 	release_mem_region(dspi->pbase, resource_size(r));
 	release_mem_region(dspi->pbase, resource_size(r));
 free_master:
 free_master:
-	kfree(master);
+	spi_master_put(master);
 err:
 err:
 	return ret;
 	return ret;
 }
 }
@@ -1051,11 +1050,11 @@ static int davinci_spi_remove(struct platform_device *pdev)
 
 
 	clk_disable_unprepare(dspi->clk);
 	clk_disable_unprepare(dspi->clk);
 	clk_put(dspi->clk);
 	clk_put(dspi->clk);
-	spi_master_put(master);
 	free_irq(dspi->irq, dspi);
 	free_irq(dspi->irq, dspi);
 	iounmap(dspi->base);
 	iounmap(dspi->base);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(dspi->pbase, resource_size(r));
 	release_mem_region(dspi->pbase, resource_size(r));
+	spi_master_put(master);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 4
drivers/spi/spi-dw-mmio.c

@@ -74,7 +74,7 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
 	dwsmmio->clk = clk_get(&pdev->dev, NULL);
 	dwsmmio->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dwsmmio->clk)) {
 	if (IS_ERR(dwsmmio->clk)) {
 		ret = PTR_ERR(dwsmmio->clk);
 		ret = PTR_ERR(dwsmmio->clk);
-		goto err_irq;
+		goto err_unmap;
 	}
 	}
 	clk_enable(dwsmmio->clk);
 	clk_enable(dwsmmio->clk);
 
 
@@ -94,8 +94,6 @@ err_clk:
 	clk_disable(dwsmmio->clk);
 	clk_disable(dwsmmio->clk);
 	clk_put(dwsmmio->clk);
 	clk_put(dwsmmio->clk);
 	dwsmmio->clk = NULL;
 	dwsmmio->clk = NULL;
-err_irq:
-	free_irq(dws->irq, dws);
 err_unmap:
 err_unmap:
 	iounmap(dws->regs);
 	iounmap(dws->regs);
 err_release_reg:
 err_release_reg:
@@ -115,7 +113,6 @@ static int dw_spi_mmio_remove(struct platform_device *pdev)
 	clk_put(dwsmmio->clk);
 	clk_put(dwsmmio->clk);
 	dwsmmio->clk = NULL;
 	dwsmmio->clk = NULL;
 
 
-	free_irq(dwsmmio->dws.irq, &dwsmmio->dws);
 	dw_spi_remove_host(&dwsmmio->dws);
 	dw_spi_remove_host(&dwsmmio->dws);
 	iounmap(dwsmmio->dws.regs);
 	iounmap(dwsmmio->dws.regs);
 	kfree(dwsmmio);
 	kfree(dwsmmio);

+ 1 - 2
drivers/spi/spi-dw-pci.c

@@ -40,7 +40,7 @@ static int spi_pci_probe(struct pci_dev *pdev,
 	int pci_bar = 0;
 	int pci_bar = 0;
 	int ret;
 	int ret;
 
 
-	printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n",
+	dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
 		pdev->vendor, pdev->device);
 		pdev->vendor, pdev->device);
 
 
 	ret = pci_enable_device(pdev);
 	ret = pci_enable_device(pdev);
@@ -109,7 +109,6 @@ static void spi_pci_remove(struct pci_dev *pdev)
 {
 {
 	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
 	struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
 
 
-	pci_set_drvdata(pdev, NULL);
 	dw_spi_remove_host(&dwpci->dws);
 	dw_spi_remove_host(&dwpci->dws);
 	iounmap(dwpci->dws.regs);
 	iounmap(dwpci->dws.regs);
 	pci_release_region(pdev, 0);
 	pci_release_region(pdev, 0);

+ 2 - 2
drivers/spi/spi-dw.c

@@ -870,8 +870,8 @@ void dw_spi_remove_host(struct dw_spi *dws)
 	/* Remove the queue */
 	/* Remove the queue */
 	status = destroy_queue(dws);
 	status = destroy_queue(dws);
 	if (status != 0)
 	if (status != 0)
-		dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not "
-			"complete, message memory not freed\n");
+		dev_err(&dws->master->dev,
+			"dw_spi_remove: workqueue will not complete, message memory not freed\n");
 
 
 	if (dws->dma_ops && dws->dma_ops->dma_exit)
 	if (dws->dma_ops && dws->dma_ops->dma_exit)
 		dws->dma_ops->dma_exit(dws);
 		dws->dma_ops->dma_exit(dws);

+ 4 - 8
drivers/spi/spi-efm32.c

@@ -280,10 +280,6 @@ static irqreturn_t efm32_spi_txirq(int irq, void *data)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static const struct efm32_spi_pdata efm32_spi_pdata_default = {
-	.location = 1,
-};
-
 static u32 efm32_spi_get_configured_location(struct efm32_spi_ddata *ddata)
 static u32 efm32_spi_get_configured_location(struct efm32_spi_ddata *ddata)
 {
 {
 	u32 reg = efm32_spi_read32(ddata, REG_ROUTE);
 	u32 reg = efm32_spi_read32(ddata, REG_ROUTE);
@@ -347,7 +343,7 @@ static int efm32_spi_probe(struct platform_device *pdev)
 
 
 	ddata = spi_master_get_devdata(master);
 	ddata = spi_master_get_devdata(master);
 
 
-	ddata->bitbang.master = spi_master_get(master);
+	ddata->bitbang.master = master;
 	ddata->bitbang.chipselect = efm32_spi_chipselect;
 	ddata->bitbang.chipselect = efm32_spi_chipselect;
 	ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;
 	ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;
 	ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;
 	ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;
@@ -387,7 +383,7 @@ static int efm32_spi_probe(struct platform_device *pdev)
 		goto err;
 		goto err;
 	}
 	}
 
 
-	if (resource_size(res) < 60) {
+	if (resource_size(res) < 0x60) {
 		ret = -EINVAL;
 		ret = -EINVAL;
 		dev_err(&pdev->dev, "memory resource too small\n");
 		dev_err(&pdev->dev, "memory resource too small\n");
 		goto err;
 		goto err;
@@ -467,7 +463,6 @@ err_disable_clk:
 		clk_disable_unprepare(ddata->clk);
 		clk_disable_unprepare(ddata->clk);
 err:
 err:
 		spi_master_put(master);
 		spi_master_put(master);
-		kfree(master);
 	}
 	}
 
 
 	return ret;
 	return ret;
@@ -478,13 +473,14 @@ static int efm32_spi_remove(struct platform_device *pdev)
 	struct spi_master *master = platform_get_drvdata(pdev);
 	struct spi_master *master = platform_get_drvdata(pdev);
 	struct efm32_spi_ddata *ddata = spi_master_get_devdata(master);
 	struct efm32_spi_ddata *ddata = spi_master_get_devdata(master);
 
 
+	spi_bitbang_stop(&ddata->bitbang);
+
 	efm32_spi_write32(ddata, 0, REG_IEN);
 	efm32_spi_write32(ddata, 0, REG_IEN);
 
 
 	free_irq(ddata->txirq, ddata);
 	free_irq(ddata->txirq, ddata);
 	free_irq(ddata->rxirq, ddata);
 	free_irq(ddata->rxirq, ddata);
 	clk_disable_unprepare(ddata->clk);
 	clk_disable_unprepare(ddata->clk);
 	spi_master_put(master);
 	spi_master_put(master);
-	kfree(master);
 
 
 	return 0;
 	return 0;
 }
 }

+ 3 - 4
drivers/spi/spi-ep93xx.c

@@ -330,7 +330,7 @@ static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi,
 
 
 	dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
 	dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n",
 		chip->spi->mode, div_cpsr, div_scr, dss);
 		chip->spi->mode, div_cpsr, div_scr, dss);
-	dev_dbg(&espi->pdev->dev, "setup: cr0 %#x", cr0);
+	dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0);
 
 
 	ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr);
 	ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr);
 	ep93xx_spi_write_u16(espi, SSPCR0, cr0);
 	ep93xx_spi_write_u16(espi, SSPCR0, cr0);
@@ -509,7 +509,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir)
 	}
 	}
 
 
 	if (WARN_ON(len)) {
 	if (WARN_ON(len)) {
-		dev_warn(&espi->pdev->dev, "len = %zu expected 0!", len);
+		dev_warn(&espi->pdev->dev, "len = %zu expected 0!\n", len);
 		return ERR_PTR(-EINVAL);
 		return ERR_PTR(-EINVAL);
 	}
 	}
 
 
@@ -942,7 +942,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
 	/* make sure that the hardware is disabled */
 	/* make sure that the hardware is disabled */
 	ep93xx_spi_write_u8(espi, SSPCR1, 0);
 	ep93xx_spi_write_u8(espi, SSPCR1, 0);
 
 
-	error = spi_register_master(master);
+	error = devm_spi_register_master(&pdev->dev, master);
 	if (error) {
 	if (error) {
 		dev_err(&pdev->dev, "failed to register SPI master\n");
 		dev_err(&pdev->dev, "failed to register SPI master\n");
 		goto fail_free_dma;
 		goto fail_free_dma;
@@ -968,7 +968,6 @@ static int ep93xx_spi_remove(struct platform_device *pdev)
 
 
 	ep93xx_spi_release_dma(espi);
 	ep93xx_spi_release_dma(espi);
 
 
-	spi_unregister_master(master);
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/spi/spi-fsl-cpm.c

@@ -299,7 +299,7 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
 
 
 		switch (mspi->subblock) {
 		switch (mspi->subblock) {
 		default:
 		default:
-			dev_warn(dev, "cell-index unspecified, assuming SPI1");
+			dev_warn(dev, "cell-index unspecified, assuming SPI1\n");
 			/* fall through */
 			/* fall through */
 		case 0:
 		case 0:
 			mspi->subblock = QE_CR_SUBBLOCK_SPI1;
 			mspi->subblock = QE_CR_SUBBLOCK_SPI1;

+ 5 - 5
drivers/spi/spi-fsl-dspi.c

@@ -108,7 +108,7 @@ struct fsl_dspi {
 	struct spi_bitbang	bitbang;
 	struct spi_bitbang	bitbang;
 	struct platform_device	*pdev;
 	struct platform_device	*pdev;
 
 
-	void			*base;
+	void __iomem		*base;
 	int			irq;
 	int			irq;
 	struct clk 		*clk;
 	struct clk 		*clk;
 
 
@@ -165,7 +165,7 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
 			}
 			}
 		}
 		}
 
 
-	pr_warn("Can not find valid buad rate,speed_hz is %d,clkrate is %ld\
+	pr_warn("Can not find valid baud rate,speed_hz is %d,clkrate is %ld\
 		,we use the max prescaler value.\n", speed_hz, clkrate);
 		,we use the max prescaler value.\n", speed_hz, clkrate);
 	*pbr = ARRAY_SIZE(pbr_tbl) - 1;
 	*pbr = ARRAY_SIZE(pbr_tbl) - 1;
 	*br =  ARRAY_SIZE(brs) - 1;
 	*br =  ARRAY_SIZE(brs) - 1;
@@ -450,7 +450,7 @@ static int dspi_probe(struct platform_device *pdev)
 
 
 	dspi = spi_master_get_devdata(master);
 	dspi = spi_master_get_devdata(master);
 	dspi->pdev = pdev;
 	dspi->pdev = pdev;
-	dspi->bitbang.master = spi_master_get(master);
+	dspi->bitbang.master = master;
 	dspi->bitbang.chipselect = dspi_chipselect;
 	dspi->bitbang.chipselect = dspi_chipselect;
 	dspi->bitbang.setup_transfer = dspi_setup_transfer;
 	dspi->bitbang.setup_transfer = dspi_setup_transfer;
 	dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
 	dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
@@ -520,7 +520,6 @@ out_clk_put:
 	clk_disable_unprepare(dspi->clk);
 	clk_disable_unprepare(dspi->clk);
 out_master_put:
 out_master_put:
 	spi_master_put(master);
 	spi_master_put(master);
-	platform_set_drvdata(pdev, NULL);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -531,6 +530,7 @@ static int dspi_remove(struct platform_device *pdev)
 
 
 	/* Disconnect from the SPI framework */
 	/* Disconnect from the SPI framework */
 	spi_bitbang_stop(&dspi->bitbang);
 	spi_bitbang_stop(&dspi->bitbang);
+	clk_disable_unprepare(dspi->clk);
 	spi_master_put(dspi->bitbang.master);
 	spi_master_put(dspi->bitbang.master);
 
 
 	return 0;
 	return 0;
@@ -547,5 +547,5 @@ static struct platform_driver fsl_dspi_driver = {
 module_platform_driver(fsl_dspi_driver);
 module_platform_driver(fsl_dspi_driver);
 
 
 MODULE_DESCRIPTION("Freescale DSPI Controller Driver");
 MODULE_DESCRIPTION("Freescale DSPI Controller Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_ALIAS("platform:" DRIVER_NAME);

+ 2 - 2
drivers/spi/spi-fsl-espi.c

@@ -289,8 +289,8 @@ static void fsl_espi_do_trans(struct spi_message *m,
 		if ((first->bits_per_word != t->bits_per_word) ||
 		if ((first->bits_per_word != t->bits_per_word) ||
 			(first->speed_hz != t->speed_hz)) {
 			(first->speed_hz != t->speed_hz)) {
 			espi_trans->status = -EINVAL;
 			espi_trans->status = -EINVAL;
-			dev_err(mspi->dev, "bits_per_word/speed_hz should be"
-					" same for the same SPI transfer\n");
+			dev_err(mspi->dev,
+				"bits_per_word/speed_hz should be same for the same SPI transfer\n");
 			return;
 			return;
 		}
 		}
 
 

+ 3 - 3
drivers/spi/spi-gpio.c

@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 
 
@@ -467,7 +468,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
 	}
 	}
 #endif
 #endif
 
 
-	spi_gpio->bitbang.master = spi_master_get(master);
+	spi_gpio->bitbang.master = master;
 	spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
 	spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
 
 
 	if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
 	if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
@@ -486,7 +487,6 @@ static int spi_gpio_probe(struct platform_device *pdev)
 
 
 	status = spi_bitbang_start(&spi_gpio->bitbang);
 	status = spi_bitbang_start(&spi_gpio->bitbang);
 	if (status < 0) {
 	if (status < 0) {
-		spi_master_put(spi_gpio->bitbang.master);
 gpio_free:
 gpio_free:
 		if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
 		if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
 			gpio_free(SPI_MISO_GPIO);
 			gpio_free(SPI_MISO_GPIO);
@@ -510,13 +510,13 @@ static int spi_gpio_remove(struct platform_device *pdev)
 
 
 	/* stop() unregisters child devices too */
 	/* stop() unregisters child devices too */
 	status = spi_bitbang_stop(&spi_gpio->bitbang);
 	status = spi_bitbang_stop(&spi_gpio->bitbang);
-	spi_master_put(spi_gpio->bitbang.master);
 
 
 	if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
 	if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
 		gpio_free(SPI_MISO_GPIO);
 		gpio_free(SPI_MISO_GPIO);
 	if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
 	if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
 		gpio_free(SPI_MOSI_GPIO);
 		gpio_free(SPI_MOSI_GPIO);
 	gpio_free(SPI_SCK_GPIO);
 	gpio_free(SPI_SCK_GPIO);
+	spi_master_put(spi_gpio->bitbang.master);
 
 
 	return status;
 	return status;
 }
 }

+ 34 - 1
drivers/spi/spi-imx.c

@@ -749,6 +749,35 @@ static void spi_imx_cleanup(struct spi_device *spi)
 {
 {
 }
 }
 
 
+static int
+spi_imx_prepare_message(struct spi_master *master, struct spi_message *msg)
+{
+	struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
+	int ret;
+
+	ret = clk_enable(spi_imx->clk_per);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(spi_imx->clk_ipg);
+	if (ret) {
+		clk_disable(spi_imx->clk_per);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+spi_imx_unprepare_message(struct spi_master *master, struct spi_message *msg)
+{
+	struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
+
+	clk_disable(spi_imx->clk_ipg);
+	clk_disable(spi_imx->clk_per);
+	return 0;
+}
+
 static int spi_imx_probe(struct platform_device *pdev)
 static int spi_imx_probe(struct platform_device *pdev)
 {
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *np = pdev->dev.of_node;
@@ -786,7 +815,7 @@ static int spi_imx_probe(struct platform_device *pdev)
 	master->num_chipselect = num_cs;
 	master->num_chipselect = num_cs;
 
 
 	spi_imx = spi_master_get_devdata(master);
 	spi_imx = spi_master_get_devdata(master);
-	spi_imx->bitbang.master = spi_master_get(master);
+	spi_imx->bitbang.master = master;
 
 
 	for (i = 0; i < master->num_chipselect; i++) {
 	for (i = 0; i < master->num_chipselect; i++) {
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
 		int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
@@ -810,6 +839,8 @@ static int spi_imx_probe(struct platform_device *pdev)
 	spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
 	spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
 	spi_imx->bitbang.master->setup = spi_imx_setup;
 	spi_imx->bitbang.master->setup = spi_imx_setup;
 	spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
 	spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
+	spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message;
+	spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message;
 	spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 	spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
 
 	init_completion(&spi_imx->xfer_done);
 	init_completion(&spi_imx->xfer_done);
@@ -872,6 +903,8 @@ static int spi_imx_probe(struct platform_device *pdev)
 
 
 	dev_info(&pdev->dev, "probed\n");
 	dev_info(&pdev->dev, "probed\n");
 
 
+	clk_disable(spi_imx->clk_ipg);
+	clk_disable(spi_imx->clk_per);
 	return ret;
 	return ret;
 
 
 out_clk_put:
 out_clk_put:

+ 1 - 1
drivers/spi/spi-lm70llp.c

@@ -222,7 +222,7 @@ static void spi_lm70llp_attach(struct parport *p)
 	/*
 	/*
 	 * SPI and bitbang hookup.
 	 * SPI and bitbang hookup.
 	 */
 	 */
-	pp->bitbang.master = spi_master_get(master);
+	pp->bitbang.master = master;
 	pp->bitbang.chipselect = lm70_chipselect;
 	pp->bitbang.chipselect = lm70_chipselect;
 	pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;
 	pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx;
 	pp->bitbang.flags = SPI_3WIRE;
 	pp->bitbang.flags = SPI_3WIRE;

+ 1 - 3
drivers/spi/spi-mpc512x-psc.c

@@ -536,7 +536,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
 	if (ret < 0)
 	if (ret < 0)
 		goto free_clock;
 		goto free_clock;
 
 
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(dev, master);
 	if (ret < 0)
 	if (ret < 0)
 		goto free_clock;
 		goto free_clock;
 
 
@@ -559,12 +559,10 @@ static int mpc512x_psc_spi_do_remove(struct device *dev)
 	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
 	struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
 
 
-	spi_unregister_master(master);
 	clk_disable_unprepare(mps->clk_mclk);
 	clk_disable_unprepare(mps->clk_mclk);
 	free_irq(mps->irq, mps);
 	free_irq(mps->irq, mps);
 	if (mps->psc)
 	if (mps->psc)
 		iounmap(mps->psc);
 		iounmap(mps->psc);
-	spi_master_put(master);
 
 
 	return 0;
 	return 0;
 }
 }

+ 2 - 2
drivers/spi/spi-mpc52xx-psc.c

@@ -383,8 +383,8 @@ static int mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
 
 
 	mps->irq = irq;
 	mps->irq = irq;
 	if (pdata == NULL) {
 	if (pdata == NULL) {
-		dev_warn(dev, "probe called without platform data, no "
-				"cs_control function will be called\n");
+		dev_warn(dev,
+			 "probe called without platform data, no cs_control function will be called\n");
 		mps->cs_control = NULL;
 		mps->cs_control = NULL;
 		mps->sysclk = 0;
 		mps->sysclk = 0;
 		master->bus_num = bus_num;
 		master->bus_num = bus_num;

+ 81 - 112
drivers/spi/spi-mxs.c

@@ -57,34 +57,53 @@
 
 
 #define SG_MAXLEN		0xff00
 #define SG_MAXLEN		0xff00
 
 
+/*
+ * Flags for txrx functions.  More efficient that using an argument register for
+ * each one.
+ */
+#define TXRX_WRITE		(1<<0)	/* This is a write */
+#define TXRX_DEASSERT_CS	(1<<1)	/* De-assert CS at end of txrx */
+
 struct mxs_spi {
 struct mxs_spi {
 	struct mxs_ssp		ssp;
 	struct mxs_ssp		ssp;
 	struct completion	c;
 	struct completion	c;
+	unsigned int		sck;	/* Rate requested (vs actual) */
 };
 };
 
 
 static int mxs_spi_setup_transfer(struct spi_device *dev,
 static int mxs_spi_setup_transfer(struct spi_device *dev,
-				struct spi_transfer *t)
+				  const struct spi_transfer *t)
 {
 {
 	struct mxs_spi *spi = spi_master_get_devdata(dev->master);
 	struct mxs_spi *spi = spi_master_get_devdata(dev->master);
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct mxs_ssp *ssp = &spi->ssp;
-	uint32_t hz = 0;
+	const unsigned int hz = min(dev->max_speed_hz, t->speed_hz);
 
 
-	hz = dev->max_speed_hz;
-	if (t && t->speed_hz)
-		hz = min(hz, t->speed_hz);
 	if (hz == 0) {
 	if (hz == 0) {
-		dev_err(&dev->dev, "Cannot continue with zero clock\n");
+		dev_err(&dev->dev, "SPI clock rate of zero not allowed\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	mxs_ssp_set_clk_rate(ssp, hz);
+	if (hz != spi->sck) {
+		mxs_ssp_set_clk_rate(ssp, hz);
+		/*
+		 * Save requested rate, hz, rather than the actual rate,
+		 * ssp->clk_rate.  Otherwise we would set the rate every trasfer
+		 * when the actual rate is not quite the same as requested rate.
+		 */
+		spi->sck = hz;
+		/*
+		 * Perhaps we should return an error if the actual clock is
+		 * nowhere close to what was requested?
+		 */
+	}
+
+	writel(BM_SSP_CTRL0_LOCK_CS,
+		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 
 
 	writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) |
 	writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) |
-		     BF_SSP_CTRL1_WORD_LENGTH
-		     (BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) |
-		     ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) |
-		     ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0),
-		     ssp->base + HW_SSP_CTRL1(ssp));
+	       BF_SSP_CTRL1_WORD_LENGTH(BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) |
+	       ((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) |
+	       ((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0),
+	       ssp->base + HW_SSP_CTRL1(ssp));
 
 
 	writel(0x0, ssp->base + HW_SSP_CMD0);
 	writel(0x0, ssp->base + HW_SSP_CMD0);
 	writel(0x0, ssp->base + HW_SSP_CMD1);
 	writel(0x0, ssp->base + HW_SSP_CMD1);
@@ -94,26 +113,15 @@ static int mxs_spi_setup_transfer(struct spi_device *dev,
 
 
 static int mxs_spi_setup(struct spi_device *dev)
 static int mxs_spi_setup(struct spi_device *dev)
 {
 {
-	int err = 0;
-
 	if (!dev->bits_per_word)
 	if (!dev->bits_per_word)
 		dev->bits_per_word = 8;
 		dev->bits_per_word = 8;
 
 
-	if (dev->mode & ~(SPI_CPOL | SPI_CPHA))
-		return -EINVAL;
-
-	err = mxs_spi_setup_transfer(dev, NULL);
-	if (err) {
-		dev_err(&dev->dev,
-			"Failed to setup transfer, error = %d\n", err);
-	}
-
-	return err;
+	return 0;
 }
 }
 
 
-static uint32_t mxs_spi_cs_to_reg(unsigned cs)
+static u32 mxs_spi_cs_to_reg(unsigned cs)
 {
 {
-	uint32_t select = 0;
+	u32 select = 0;
 
 
 	/*
 	/*
 	 * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0
 	 * i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0
@@ -131,43 +139,11 @@ static uint32_t mxs_spi_cs_to_reg(unsigned cs)
 	return select;
 	return select;
 }
 }
 
 
-static void mxs_spi_set_cs(struct mxs_spi *spi, unsigned cs)
-{
-	const uint32_t mask =
-		BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ;
-	uint32_t select;
-	struct mxs_ssp *ssp = &spi->ssp;
-
-	writel(mask, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
-	select = mxs_spi_cs_to_reg(cs);
-	writel(select, ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
-}
-
-static inline void mxs_spi_enable(struct mxs_spi *spi)
-{
-	struct mxs_ssp *ssp = &spi->ssp;
-
-	writel(BM_SSP_CTRL0_LOCK_CS,
-		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
-	writel(BM_SSP_CTRL0_IGNORE_CRC,
-		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
-}
-
-static inline void mxs_spi_disable(struct mxs_spi *spi)
-{
-	struct mxs_ssp *ssp = &spi->ssp;
-
-	writel(BM_SSP_CTRL0_LOCK_CS,
-		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
-	writel(BM_SSP_CTRL0_IGNORE_CRC,
-		ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
-}
-
 static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)
 static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)
 {
 {
 	const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT);
 	const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT);
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct mxs_ssp *ssp = &spi->ssp;
-	uint32_t reg;
+	u32 reg;
 
 
 	do {
 	do {
 		reg = readl_relaxed(ssp->base + offset);
 		reg = readl_relaxed(ssp->base + offset);
@@ -200,9 +176,9 @@ static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
+static int mxs_spi_txrx_dma(struct mxs_spi *spi,
 			    unsigned char *buf, int len,
 			    unsigned char *buf, int len,
-			    int *first, int *last, int write)
+			    unsigned int flags)
 {
 {
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct dma_async_tx_descriptor *desc = NULL;
 	struct dma_async_tx_descriptor *desc = NULL;
@@ -211,11 +187,11 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 	const int sgs = DIV_ROUND_UP(len, desc_len);
 	const int sgs = DIV_ROUND_UP(len, desc_len);
 	int sg_count;
 	int sg_count;
 	int min, ret;
 	int min, ret;
-	uint32_t ctrl0;
+	u32 ctrl0;
 	struct page *vm_page;
 	struct page *vm_page;
 	void *sg_buf;
 	void *sg_buf;
 	struct {
 	struct {
-		uint32_t		pio[4];
+		u32			pio[4];
 		struct scatterlist	sg;
 		struct scatterlist	sg;
 	} *dma_xfer;
 	} *dma_xfer;
 
 
@@ -228,21 +204,25 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
 
 	INIT_COMPLETION(spi->c);
 	INIT_COMPLETION(spi->c);
 
 
+	/* Chip select was already programmed into CTRL0 */
 	ctrl0 = readl(ssp->base + HW_SSP_CTRL0);
 	ctrl0 = readl(ssp->base + HW_SSP_CTRL0);
-	ctrl0 &= ~BM_SSP_CTRL0_XFER_COUNT;
-	ctrl0 |= BM_SSP_CTRL0_DATA_XFER | mxs_spi_cs_to_reg(cs);
+	ctrl0 &= ~(BM_SSP_CTRL0_XFER_COUNT | BM_SSP_CTRL0_IGNORE_CRC |
+		 BM_SSP_CTRL0_READ);
+	ctrl0 |= BM_SSP_CTRL0_DATA_XFER;
 
 
-	if (*first)
-		ctrl0 |= BM_SSP_CTRL0_LOCK_CS;
-	if (!write)
+	if (!(flags & TXRX_WRITE))
 		ctrl0 |= BM_SSP_CTRL0_READ;
 		ctrl0 |= BM_SSP_CTRL0_READ;
 
 
 	/* Queue the DMA data transfer. */
 	/* Queue the DMA data transfer. */
 	for (sg_count = 0; sg_count < sgs; sg_count++) {
 	for (sg_count = 0; sg_count < sgs; sg_count++) {
+		/* Prepare the transfer descriptor. */
 		min = min(len, desc_len);
 		min = min(len, desc_len);
 
 
-		/* Prepare the transfer descriptor. */
-		if ((sg_count + 1 == sgs) && *last)
+		/*
+		 * De-assert CS on last segment if flag is set (i.e., no more
+		 * transfers will follow)
+		 */
+		if ((sg_count + 1 == sgs) && (flags & TXRX_DEASSERT_CS))
 			ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC;
 			ctrl0 |= BM_SSP_CTRL0_IGNORE_CRC;
 
 
 		if (ssp->devid == IMX23_SSP) {
 		if (ssp->devid == IMX23_SSP) {
@@ -267,7 +247,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
 
 		sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);
 		sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);
 		ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
 		ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
-			write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+			(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
 
 		len -= min;
 		len -= min;
 		buf += min;
 		buf += min;
@@ -287,7 +267,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, int cs,
 
 
 		desc = dmaengine_prep_slave_sg(ssp->dmach,
 		desc = dmaengine_prep_slave_sg(ssp->dmach,
 				&dma_xfer[sg_count].sg, 1,
 				&dma_xfer[sg_count].sg, 1,
-				write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+				(flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
 				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 
 
 		if (!desc) {
 		if (!desc) {
@@ -324,7 +304,7 @@ err_vmalloc:
 	while (--sg_count >= 0) {
 	while (--sg_count >= 0) {
 err_mapped:
 err_mapped:
 		dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
 		dma_unmap_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
-			write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+			(flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 	}
 	}
 
 
 	kfree(dma_xfer);
 	kfree(dma_xfer);
@@ -332,20 +312,19 @@ err_mapped:
 	return ret;
 	return ret;
 }
 }
 
 
-static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
+static int mxs_spi_txrx_pio(struct mxs_spi *spi,
 			    unsigned char *buf, int len,
 			    unsigned char *buf, int len,
-			    int *first, int *last, int write)
+			    unsigned int flags)
 {
 {
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct mxs_ssp *ssp = &spi->ssp;
 
 
-	if (*first)
-		mxs_spi_enable(spi);
-
-	mxs_spi_set_cs(spi, cs);
+	writel(BM_SSP_CTRL0_IGNORE_CRC,
+	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
 
 
 	while (len--) {
 	while (len--) {
-		if (*last && len == 0)
-			mxs_spi_disable(spi);
+		if (len == 0 && (flags & TXRX_DEASSERT_CS))
+			writel(BM_SSP_CTRL0_IGNORE_CRC,
+			       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 
 
 		if (ssp->devid == IMX23_SSP) {
 		if (ssp->devid == IMX23_SSP) {
 			writel(BM_SSP_CTRL0_XFER_COUNT,
 			writel(BM_SSP_CTRL0_XFER_COUNT,
@@ -356,7 +335,7 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
 			writel(1, ssp->base + HW_SSP_XFER_SIZE);
 			writel(1, ssp->base + HW_SSP_XFER_SIZE);
 		}
 		}
 
 
-		if (write)
+		if (flags & TXRX_WRITE)
 			writel(BM_SSP_CTRL0_READ,
 			writel(BM_SSP_CTRL0_READ,
 				ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
 				ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
 		else
 		else
@@ -369,13 +348,13 @@ static int mxs_spi_txrx_pio(struct mxs_spi *spi, int cs,
 		if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1))
 		if (mxs_ssp_wait(spi, HW_SSP_CTRL0, BM_SSP_CTRL0_RUN, 1))
 			return -ETIMEDOUT;
 			return -ETIMEDOUT;
 
 
-		if (write)
+		if (flags & TXRX_WRITE)
 			writel(*buf, ssp->base + HW_SSP_DATA(ssp));
 			writel(*buf, ssp->base + HW_SSP_DATA(ssp));
 
 
 		writel(BM_SSP_CTRL0_DATA_XFER,
 		writel(BM_SSP_CTRL0_DATA_XFER,
 			     ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 			     ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 
 
-		if (!write) {
+		if (!(flags & TXRX_WRITE)) {
 			if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp),
 			if (mxs_ssp_wait(spi, HW_SSP_STATUS(ssp),
 						BM_SSP_STATUS_FIFO_EMPTY, 0))
 						BM_SSP_STATUS_FIFO_EMPTY, 0))
 				return -ETIMEDOUT;
 				return -ETIMEDOUT;
@@ -400,14 +379,15 @@ static int mxs_spi_transfer_one(struct spi_master *master,
 {
 {
 	struct mxs_spi *spi = spi_master_get_devdata(master);
 	struct mxs_spi *spi = spi_master_get_devdata(master);
 	struct mxs_ssp *ssp = &spi->ssp;
 	struct mxs_ssp *ssp = &spi->ssp;
-	int first, last;
 	struct spi_transfer *t, *tmp_t;
 	struct spi_transfer *t, *tmp_t;
+	unsigned int flag;
 	int status = 0;
 	int status = 0;
-	int cs;
-
-	first = last = 0;
 
 
-	cs = m->spi->chip_select;
+	/* Program CS register bits here, it will be used for all transfers. */
+	writel(BM_SSP_CTRL0_WAIT_FOR_CMD | BM_SSP_CTRL0_WAIT_FOR_IRQ,
+	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
+	writel(mxs_spi_cs_to_reg(m->spi->chip_select),
+	       ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
 
 
 	list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) {
 	list_for_each_entry_safe(t, tmp_t, &m->transfers, transfer_list) {
 
 
@@ -415,16 +395,9 @@ static int mxs_spi_transfer_one(struct spi_master *master,
 		if (status)
 		if (status)
 			break;
 			break;
 
 
-		if (&t->transfer_list == m->transfers.next)
-			first = 1;
-		if (&t->transfer_list == m->transfers.prev)
-			last = 1;
-		if ((t->rx_buf && t->tx_buf) || (t->rx_dma && t->tx_dma)) {
-			dev_err(ssp->dev,
-				"Cannot send and receive simultaneously\n");
-			status = -EINVAL;
-			break;
-		}
+		/* De-assert on last transfer, inverted by cs_change flag */
+		flag = (&t->transfer_list == m->transfers.prev) ^ t->cs_change ?
+		       TXRX_DEASSERT_CS : 0;
 
 
 		/*
 		/*
 		 * Small blocks can be transfered via PIO.
 		 * Small blocks can be transfered via PIO.
@@ -441,26 +414,26 @@ static int mxs_spi_transfer_one(struct spi_master *master,
 				STMP_OFFSET_REG_CLR);
 				STMP_OFFSET_REG_CLR);
 
 
 			if (t->tx_buf)
 			if (t->tx_buf)
-				status = mxs_spi_txrx_pio(spi, cs,
+				status = mxs_spi_txrx_pio(spi,
 						(void *)t->tx_buf,
 						(void *)t->tx_buf,
-						t->len, &first, &last, 1);
+						t->len, flag | TXRX_WRITE);
 			if (t->rx_buf)
 			if (t->rx_buf)
-				status = mxs_spi_txrx_pio(spi, cs,
+				status = mxs_spi_txrx_pio(spi,
 						t->rx_buf, t->len,
 						t->rx_buf, t->len,
-						&first, &last, 0);
+						flag);
 		} else {
 		} else {
 			writel(BM_SSP_CTRL1_DMA_ENABLE,
 			writel(BM_SSP_CTRL1_DMA_ENABLE,
 				ssp->base + HW_SSP_CTRL1(ssp) +
 				ssp->base + HW_SSP_CTRL1(ssp) +
 				STMP_OFFSET_REG_SET);
 				STMP_OFFSET_REG_SET);
 
 
 			if (t->tx_buf)
 			if (t->tx_buf)
-				status = mxs_spi_txrx_dma(spi, cs,
+				status = mxs_spi_txrx_dma(spi,
 						(void *)t->tx_buf, t->len,
 						(void *)t->tx_buf, t->len,
-						&first, &last, 1);
+						flag | TXRX_WRITE);
 			if (t->rx_buf)
 			if (t->rx_buf)
-				status = mxs_spi_txrx_dma(spi, cs,
+				status = mxs_spi_txrx_dma(spi,
 						t->rx_buf, t->len,
 						t->rx_buf, t->len,
-						&first, &last, 0);
+						flag);
 		}
 		}
 
 
 		if (status) {
 		if (status) {
@@ -469,7 +442,6 @@ static int mxs_spi_transfer_one(struct spi_master *master,
 		}
 		}
 
 
 		m->actual_length += t->len;
 		m->actual_length += t->len;
-		first = last = 0;
 	}
 	}
 
 
 	m->status = status;
 	m->status = status;
@@ -563,7 +535,6 @@ static int mxs_spi_probe(struct platform_device *pdev)
 		goto out_dma_release;
 		goto out_dma_release;
 
 
 	clk_set_rate(ssp->clk, clk_freq);
 	clk_set_rate(ssp->clk, clk_freq);
-	ssp->clk_rate = clk_get_rate(ssp->clk) / 1000;
 
 
 	ret = stmp_reset_block(ssp->base);
 	ret = stmp_reset_block(ssp->base);
 	if (ret)
 	if (ret)
@@ -571,7 +542,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
 
 
 	platform_set_drvdata(pdev, master);
 	platform_set_drvdata(pdev, master);
 
 
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
 		dev_err(&pdev->dev, "Cannot register SPI master, %d\n", ret);
 		goto out_disable_clk;
 		goto out_disable_clk;
@@ -598,10 +569,8 @@ static int mxs_spi_remove(struct platform_device *pdev)
 	spi = spi_master_get_devdata(master);
 	spi = spi_master_get_devdata(master);
 	ssp = &spi->ssp;
 	ssp = &spi->ssp;
 
 
-	spi_unregister_master(master);
 	clk_disable_unprepare(ssp->clk);
 	clk_disable_unprepare(ssp->clk);
 	dma_release_channel(ssp->dmach);
 	dma_release_channel(ssp->dmach);
-	spi_master_put(master);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 2
drivers/spi/spi-nuc900.c

@@ -349,7 +349,7 @@ static int nuc900_spi_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	hw = spi_master_get_devdata(master);
 	hw = spi_master_get_devdata(master);
-	hw->master = spi_master_get(master);
+	hw->master = master;
 	hw->pdata  = dev_get_platdata(&pdev->dev);
 	hw->pdata  = dev_get_platdata(&pdev->dev);
 	hw->dev = &pdev->dev;
 	hw->dev = &pdev->dev;
 
 
@@ -435,7 +435,6 @@ err_iomap:
 	kfree(hw->ioarea);
 	kfree(hw->ioarea);
 err_pdata:
 err_pdata:
 	spi_master_put(hw->master);
 	spi_master_put(hw->master);
-
 err_nomem:
 err_nomem:
 	return err;
 	return err;
 }
 }

+ 1 - 1
drivers/spi/spi-oc-tiny.c

@@ -306,7 +306,7 @@ static int tiny_spi_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, hw);
 	platform_set_drvdata(pdev, hw);
 
 
 	/* setup the state for the bitbang driver */
 	/* setup the state for the bitbang driver */
-	hw->bitbang.master = spi_master_get(master);
+	hw->bitbang.master = master;
 	if (!hw->bitbang.master)
 	if (!hw->bitbang.master)
 		return err;
 		return err;
 	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
 	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;

+ 1 - 3
drivers/spi/spi-octeon.c

@@ -272,7 +272,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
 	master->bits_per_word_mask = SPI_BPW_MASK(8);
 	master->bits_per_word_mask = SPI_BPW_MASK(8);
 
 
 	master->dev.of_node = pdev->dev.of_node;
 	master->dev.of_node = pdev->dev.of_node;
-	err = spi_register_master(master);
+	err = devm_spi_register_master(&pdev->dev, master);
 	if (err) {
 	if (err) {
 		dev_err(&pdev->dev, "register master failed: %d\n", err);
 		dev_err(&pdev->dev, "register master failed: %d\n", err);
 		goto fail;
 		goto fail;
@@ -292,8 +292,6 @@ static int octeon_spi_remove(struct platform_device *pdev)
 	struct octeon_spi *p = spi_master_get_devdata(master);
 	struct octeon_spi *p = spi_master_get_devdata(master);
 	u64 register_base = p->register_base;
 	u64 register_base = p->register_base;
 
 
-	spi_unregister_master(master);
-
 	/* Clear the CSENA* and put everything in a known state. */
 	/* Clear the CSENA* and put everything in a known state. */
 	cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
 	cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
 
 

+ 1 - 3
drivers/spi/spi-omap-100k.c

@@ -457,7 +457,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
 		goto err;
 		goto err;
 	}
 	}
 
 
-	status = spi_register_master(master);
+	status = devm_spi_register_master(&pdev->dev, master);
 	if (status < 0)
 	if (status < 0)
 		goto err;
 		goto err;
 
 
@@ -485,8 +485,6 @@ static int omap1_spi100k_remove(struct platform_device *pdev)
 
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 
-	spi_unregister_master(master);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 3 - 2
drivers/spi/spi-omap-uwire.c

@@ -557,7 +557,8 @@ static struct platform_driver uwire_driver = {
 		.name		= "omap_uwire",
 		.name		= "omap_uwire",
 		.owner		= THIS_MODULE,
 		.owner		= THIS_MODULE,
 	},
 	},
-	.remove		= uwire_remove,
+	.probe = uwire_probe,
+	.remove = uwire_remove,
 	// suspend ... unuse ck
 	// suspend ... unuse ck
 	// resume ... use ck
 	// resume ... use ck
 };
 };
@@ -579,7 +580,7 @@ static int __init omap_uwire_init(void)
 		omap_writel(val | 0x00AAA000, OMAP7XX_IO_CONF_9);
 		omap_writel(val | 0x00AAA000, OMAP7XX_IO_CONF_9);
 	}
 	}
 
 
-	return platform_driver_probe(&uwire_driver, uwire_probe);
+	return platform_driver_register(&uwire_driver);
 }
 }
 
 
 static void __exit omap_uwire_exit(void)
 static void __exit omap_uwire_exit(void)

+ 12 - 7
drivers/spi/spi-omap2-mcspi.c

@@ -276,7 +276,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
 	struct omap2_mcspi *mcspi;
 	unsigned int wcnt;
 	unsigned int wcnt;
-	int fifo_depth, bytes_per_word;
+	int max_fifo_depth, fifo_depth, bytes_per_word;
 	u32 chconf, xferlevel;
 	u32 chconf, xferlevel;
 
 
 	mcspi = spi_master_get_devdata(master);
 	mcspi = spi_master_get_devdata(master);
@@ -287,7 +287,12 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 		if (t->len % bytes_per_word != 0)
 		if (t->len % bytes_per_word != 0)
 			goto disable_fifo;
 			goto disable_fifo;
 
 
-		fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH);
+		if (t->rx_buf != NULL && t->tx_buf != NULL)
+			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH / 2;
+		else
+			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH;
+
+		fifo_depth = gcd(t->len, max_fifo_depth);
 		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
 		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
 			goto disable_fifo;
 			goto disable_fifo;
 
 
@@ -299,7 +304,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 		if (t->rx_buf != NULL) {
 		if (t->rx_buf != NULL) {
 			chconf |= OMAP2_MCSPI_CHCONF_FFER;
 			chconf |= OMAP2_MCSPI_CHCONF_FFER;
 			xferlevel |= (fifo_depth - 1) << 8;
 			xferlevel |= (fifo_depth - 1) << 8;
-		} else {
+		}
+		if (t->tx_buf != NULL) {
 			chconf |= OMAP2_MCSPI_CHCONF_FFET;
 			chconf |= OMAP2_MCSPI_CHCONF_FFET;
 			xferlevel |= fifo_depth - 1;
 			xferlevel |= fifo_depth - 1;
 		}
 		}
@@ -498,7 +504,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 				((u32 *)xfer->rx_buf)[elements++] = w;
 				((u32 *)xfer->rx_buf)[elements++] = w;
 		} else {
 		} else {
 			int bytes_per_word = mcspi_bytes_per_word(word_len);
 			int bytes_per_word = mcspi_bytes_per_word(word_len);
-			dev_err(&spi->dev, "DMA RX penultimate word empty");
+			dev_err(&spi->dev, "DMA RX penultimate word empty\n");
 			count -= (bytes_per_word << 1);
 			count -= (bytes_per_word << 1);
 			omap2_mcspi_set_enable(spi, 1);
 			omap2_mcspi_set_enable(spi, 1);
 			return count;
 			return count;
@@ -516,7 +522,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,
 		else /* word_len <= 32 */
 		else /* word_len <= 32 */
 			((u32 *)xfer->rx_buf)[elements] = w;
 			((u32 *)xfer->rx_buf)[elements] = w;
 	} else {
 	} else {
-		dev_err(&spi->dev, "DMA RX last word empty");
+		dev_err(&spi->dev, "DMA RX last word empty\n");
 		count -= mcspi_bytes_per_word(word_len);
 		count -= mcspi_bytes_per_word(word_len);
 	}
 	}
 	omap2_mcspi_set_enable(spi, 1);
 	omap2_mcspi_set_enable(spi, 1);
@@ -1407,7 +1413,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 	if (status < 0)
 	if (status < 0)
 		goto disable_pm;
 		goto disable_pm;
 
 
-	status = spi_register_master(master);
+	status = devm_spi_register_master(&pdev->dev, master);
 	if (status < 0)
 	if (status < 0)
 		goto disable_pm;
 		goto disable_pm;
 
 
@@ -1435,7 +1441,6 @@ static int omap2_mcspi_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(mcspi->dev);
 	pm_runtime_put_sync(mcspi->dev);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 
-	spi_unregister_master(master);
 	kfree(dma_channels);
 	kfree(dma_channels);
 
 
 	return 0;
 	return 0;

+ 4 - 6
drivers/spi/spi-orion.c

@@ -84,8 +84,8 @@ static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size)
 		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
 		orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
 				  ORION_SPI_IF_8_16_BIT_MODE);
 				  ORION_SPI_IF_8_16_BIT_MODE);
 	} else {
 	} else {
-		pr_debug("Bad bits per word value %d (only 8 or 16 are "
-			 "allowed).\n", size);
+		pr_debug("Bad bits per word value %d (only 8 or 16 are allowed).\n",
+			size);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -407,7 +407,7 @@ static int orion_spi_probe(struct platform_device *pdev)
 	const u32 *iprop;
 	const u32 *iprop;
 	int size;
 	int size;
 
 
-	master = spi_alloc_master(&pdev->dev, sizeof *spi);
+	master = spi_alloc_master(&pdev->dev, sizeof(*spi));
 	if (master == NULL) {
 	if (master == NULL) {
 		dev_dbg(&pdev->dev, "master allocation failed\n");
 		dev_dbg(&pdev->dev, "master allocation failed\n");
 		return -ENOMEM;
 		return -ENOMEM;
@@ -457,7 +457,7 @@ static int orion_spi_probe(struct platform_device *pdev)
 		goto out_rel_clk;
 		goto out_rel_clk;
 
 
 	master->dev.of_node = pdev->dev.of_node;
 	master->dev.of_node = pdev->dev.of_node;
-	status = spi_register_master(master);
+	status = devm_spi_register_master(&pdev->dev, master);
 	if (status < 0)
 	if (status < 0)
 		goto out_rel_clk;
 		goto out_rel_clk;
 
 
@@ -483,8 +483,6 @@ static int orion_spi_remove(struct platform_device *pdev)
 	clk_disable_unprepare(spi->clk);
 	clk_disable_unprepare(spi->clk);
 	clk_put(spi->clk);
 	clk_put(spi->clk);
 
 
-	spi_unregister_master(master);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 3 - 7
drivers/spi/spi-pl022.c

@@ -1619,7 +1619,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
 		dev_err(&pl022->adev->dev,
 		dev_err(&pl022->adev->dev,
 			"RX FIFO Trigger Level is configured incorrectly\n");
 			"RX FIFO Trigger Level is configured incorrectly\n");
 		return -EINVAL;
 		return -EINVAL;
-		break;
 	}
 	}
 	switch (chip_info->tx_lev_trig) {
 	switch (chip_info->tx_lev_trig) {
 	case SSP_TX_1_OR_MORE_EMPTY_LOC:
 	case SSP_TX_1_OR_MORE_EMPTY_LOC:
@@ -1645,7 +1644,6 @@ static int verify_controller_parameters(struct pl022 *pl022,
 		dev_err(&pl022->adev->dev,
 		dev_err(&pl022->adev->dev,
 			"TX FIFO Trigger Level is configured incorrectly\n");
 			"TX FIFO Trigger Level is configured incorrectly\n");
 		return -EINVAL;
 		return -EINVAL;
-		break;
 	}
 	}
 	if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) {
 	if (chip_info->iface == SSP_INTERFACE_NATIONAL_MICROWIRE) {
 		if ((chip_info->ctrl_len < SSP_BITS_4)
 		if ((chip_info->ctrl_len < SSP_BITS_4)
@@ -2175,8 +2173,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 		status = -ENOMEM;
 		status = -ENOMEM;
 		goto err_no_ioremap;
 		goto err_no_ioremap;
 	}
 	}
-	printk(KERN_INFO "pl022: mapped registers from %pa to %p\n",
-	       &adev->res.start, pl022->virtbase);
+	dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+		&adev->res.start, pl022->virtbase);
 
 
 	pl022->clk = devm_clk_get(&adev->dev, NULL);
 	pl022->clk = devm_clk_get(&adev->dev, NULL);
 	if (IS_ERR(pl022->clk)) {
 	if (IS_ERR(pl022->clk)) {
@@ -2227,7 +2225,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
 
 
 	/* Register with the SPI framework */
 	/* Register with the SPI framework */
 	amba_set_drvdata(adev, pl022);
 	amba_set_drvdata(adev, pl022);
-	status = spi_register_master(master);
+	status = devm_spi_register_master(&adev->dev, master);
 	if (status != 0) {
 	if (status != 0) {
 		dev_err(&adev->dev,
 		dev_err(&adev->dev,
 			"probe - problem registering spi master\n");
 			"probe - problem registering spi master\n");
@@ -2287,8 +2285,6 @@ pl022_remove(struct amba_device *adev)
 	clk_unprepare(pl022->clk);
 	clk_unprepare(pl022->clk);
 	amba_release_regions(adev);
 	amba_release_regions(adev);
 	tasklet_disable(&pl022->pump_transfers);
 	tasklet_disable(&pl022->pump_transfers);
-	spi_unregister_master(pl022->master);
-	amba_set_drvdata(adev, NULL);
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 1
drivers/spi/spi-ppc4xx.c

@@ -396,7 +396,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op)
 	master->dev.of_node = np;
 	master->dev.of_node = np;
 	platform_set_drvdata(op, master);
 	platform_set_drvdata(op, master);
 	hw = spi_master_get_devdata(master);
 	hw = spi_master_get_devdata(master);
-	hw->master = spi_master_get(master);
+	hw->master = master;
 	hw->dev = dev;
 	hw->dev = dev;
 
 
 	init_completion(&hw->done);
 	init_completion(&hw->done);
@@ -558,6 +558,7 @@ static int spi_ppc4xx_of_remove(struct platform_device *op)
 	free_irq(hw->irqnum, hw);
 	free_irq(hw->irqnum, hw);
 	iounmap(hw->regs);
 	iounmap(hw->regs);
 	free_gpios(hw);
 	free_gpios(hw);
+	spi_master_put(master);
 	return 0;
 	return 0;
 }
 }
 
 

+ 17 - 24
drivers/spi/spi-pxa2xx.c

@@ -573,8 +573,8 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
 			write_SSTO(0, reg);
 			write_SSTO(0, reg);
 		write_SSSR_CS(drv_data, drv_data->clear_sr);
 		write_SSSR_CS(drv_data, drv_data->clear_sr);
 
 
-		dev_err(&drv_data->pdev->dev, "bad message state "
-			"in interrupt handler\n");
+		dev_err(&drv_data->pdev->dev,
+			"bad message state in interrupt handler\n");
 
 
 		/* Never fail */
 		/* Never fail */
 		return IRQ_HANDLED;
 		return IRQ_HANDLED;
@@ -651,8 +651,8 @@ static void pump_transfers(unsigned long data)
 		if (message->is_dma_mapped
 		if (message->is_dma_mapped
 				|| transfer->rx_dma || transfer->tx_dma) {
 				|| transfer->rx_dma || transfer->tx_dma) {
 			dev_err(&drv_data->pdev->dev,
 			dev_err(&drv_data->pdev->dev,
-				"pump_transfers: mapped transfer length "
-				"of %u is greater than %d\n",
+				"pump_transfers: mapped transfer length of "
+				"%u is greater than %d\n",
 				transfer->len, MAX_DMA_LEN);
 				transfer->len, MAX_DMA_LEN);
 			message->status = -EINVAL;
 			message->status = -EINVAL;
 			giveback(drv_data);
 			giveback(drv_data);
@@ -660,11 +660,10 @@ static void pump_transfers(unsigned long data)
 		}
 		}
 
 
 		/* warn ... we force this to PIO mode */
 		/* warn ... we force this to PIO mode */
-		if (printk_ratelimit())
-			dev_warn(&message->spi->dev, "pump_transfers: "
-				"DMA disabled for transfer length %ld "
-				"greater than %d\n",
-				(long)drv_data->len, MAX_DMA_LEN);
+		dev_warn_ratelimited(&message->spi->dev,
+				     "pump_transfers: DMA disabled for transfer length %ld "
+				     "greater than %d\n",
+				     (long)drv_data->len, MAX_DMA_LEN);
 	}
 	}
 
 
 	/* Setup the transfer state based on the type of transfer */
 	/* Setup the transfer state based on the type of transfer */
@@ -726,11 +725,8 @@ static void pump_transfers(unsigned long data)
 							message->spi,
 							message->spi,
 							bits, &dma_burst,
 							bits, &dma_burst,
 							&dma_thresh))
 							&dma_thresh))
-				if (printk_ratelimit())
-					dev_warn(&message->spi->dev,
-						"pump_transfers: "
-						"DMA burst size reduced to "
-						"match bits_per_word\n");
+				dev_warn_ratelimited(&message->spi->dev,
+						     "pump_transfers: DMA burst size reduced to match bits_per_word\n");
 		}
 		}
 
 
 		cr0 = clk_div
 		cr0 = clk_div
@@ -854,8 +850,8 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip,
 	if (gpio_is_valid(chip_info->gpio_cs)) {
 	if (gpio_is_valid(chip_info->gpio_cs)) {
 		err = gpio_request(chip_info->gpio_cs, "SPI_CS");
 		err = gpio_request(chip_info->gpio_cs, "SPI_CS");
 		if (err) {
 		if (err) {
-			dev_err(&spi->dev, "failed to request chip select "
-					"GPIO%d\n", chip_info->gpio_cs);
+			dev_err(&spi->dev, "failed to request chip select GPIO%d\n",
+				chip_info->gpio_cs);
 			return err;
 			return err;
 		}
 		}
 
 
@@ -899,8 +895,8 @@ static int setup(struct spi_device *spi)
 
 
 		if (drv_data->ssp_type == CE4100_SSP) {
 		if (drv_data->ssp_type == CE4100_SSP) {
 			if (spi->chip_select > 4) {
 			if (spi->chip_select > 4) {
-				dev_err(&spi->dev, "failed setup: "
-				"cs number must not be > 4.\n");
+				dev_err(&spi->dev,
+					"failed setup: cs number must not be > 4.\n");
 				kfree(chip);
 				kfree(chip);
 				return -EINVAL;
 				return -EINVAL;
 			}
 			}
@@ -956,8 +952,8 @@ static int setup(struct spi_device *spi)
 						spi->bits_per_word,
 						spi->bits_per_word,
 						&chip->dma_burst_size,
 						&chip->dma_burst_size,
 						&chip->dma_threshold)) {
 						&chip->dma_threshold)) {
-			dev_warn(&spi->dev, "in setup: DMA burst size reduced "
-					"to match bits_per_word\n");
+			dev_warn(&spi->dev,
+				 "in setup: DMA burst size reduced to match bits_per_word\n");
 		}
 		}
 	}
 	}
 
 
@@ -1205,7 +1201,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 
 
 	/* Register with the SPI framework */
 	/* Register with the SPI framework */
 	platform_set_drvdata(pdev, drv_data);
 	platform_set_drvdata(pdev, drv_data);
-	status = spi_register_master(master);
+	status = devm_spi_register_master(&pdev->dev, master);
 	if (status != 0) {
 	if (status != 0) {
 		dev_err(&pdev->dev, "problem registering spi master\n");
 		dev_err(&pdev->dev, "problem registering spi master\n");
 		goto out_error_clock_enabled;
 		goto out_error_clock_enabled;
@@ -1257,9 +1253,6 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
 	/* Release SSP */
 	/* Release SSP */
 	pxa_ssp_free(ssp);
 	pxa_ssp_free(ssp);
 
 
-	/* Disconnect from the SPI framework */
-	spi_unregister_master(drv_data->master);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 231 - 39
drivers/spi/spi-rspi.c

@@ -59,6 +59,14 @@
 #define RSPI_SPCMD6		0x1c
 #define RSPI_SPCMD6		0x1c
 #define RSPI_SPCMD7		0x1e
 #define RSPI_SPCMD7		0x1e
 
 
+/*qspi only */
+#define QSPI_SPBFCR		0x18
+#define QSPI_SPBDCR		0x1a
+#define QSPI_SPBMUL0		0x1c
+#define QSPI_SPBMUL1		0x20
+#define QSPI_SPBMUL2		0x24
+#define QSPI_SPBMUL3		0x28
+
 /* SPCR */
 /* SPCR */
 #define SPCR_SPRIE		0x80
 #define SPCR_SPRIE		0x80
 #define SPCR_SPE		0x40
 #define SPCR_SPE		0x40
@@ -126,6 +134,8 @@
 #define SPCMD_LSBF		0x1000
 #define SPCMD_LSBF		0x1000
 #define SPCMD_SPB_MASK		0x0f00
 #define SPCMD_SPB_MASK		0x0f00
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
 #define SPCMD_SPB_8_TO_16(bit)	(((bit - 1) << 8) & SPCMD_SPB_MASK)
+#define SPCMD_SPB_8BIT		0x0000	/* qspi only */
+#define SPCMD_SPB_16BIT		0x0100
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_20BIT		0x0000
 #define SPCMD_SPB_24BIT		0x0100
 #define SPCMD_SPB_24BIT		0x0100
 #define SPCMD_SPB_32BIT		0x0200
 #define SPCMD_SPB_32BIT		0x0200
@@ -135,6 +145,10 @@
 #define SPCMD_CPOL		0x0002
 #define SPCMD_CPOL		0x0002
 #define SPCMD_CPHA		0x0001
 #define SPCMD_CPHA		0x0001
 
 
+/* SPBFCR */
+#define SPBFCR_TXRST		0x80	/* qspi only */
+#define SPBFCR_RXRST		0x40	/* qspi only */
+
 struct rspi_data {
 struct rspi_data {
 	void __iomem *addr;
 	void __iomem *addr;
 	u32 max_speed_hz;
 	u32 max_speed_hz;
@@ -145,6 +159,7 @@ struct rspi_data {
 	spinlock_t lock;
 	spinlock_t lock;
 	struct clk *clk;
 	struct clk *clk;
 	unsigned char spsr;
 	unsigned char spsr;
+	const struct spi_ops *ops;
 
 
 	/* for dmaengine */
 	/* for dmaengine */
 	struct dma_chan *chan_tx;
 	struct dma_chan *chan_tx;
@@ -165,6 +180,11 @@ static void rspi_write16(struct rspi_data *rspi, u16 data, u16 offset)
 	iowrite16(data, rspi->addr + offset);
 	iowrite16(data, rspi->addr + offset);
 }
 }
 
 
+static void rspi_write32(struct rspi_data *rspi, u32 data, u16 offset)
+{
+	iowrite32(data, rspi->addr + offset);
+}
+
 static u8 rspi_read8(struct rspi_data *rspi, u16 offset)
 static u8 rspi_read8(struct rspi_data *rspi, u16 offset)
 {
 {
 	return ioread8(rspi->addr + offset);
 	return ioread8(rspi->addr + offset);
@@ -175,17 +195,103 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset)
 	return ioread16(rspi->addr + offset);
 	return ioread16(rspi->addr + offset);
 }
 }
 
 
-static unsigned char rspi_calc_spbr(struct rspi_data *rspi)
+/* optional functions */
+struct spi_ops {
+	int (*set_config_register)(struct rspi_data *rspi, int access_size);
+	int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg,
+			struct spi_transfer *t);
+	int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg,
+			   struct spi_transfer *t);
+
+};
+
+/*
+ * functions for RSPI
+ */
+static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
+{
+	int spbr;
+
+	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
+	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+
+	/* Sets transfer bit rate */
+	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
+	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
+
+	/* Sets number of frames to be used: 1 frame */
+	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+
+	/* Sets RSPCK, SSL, next-access delay value */
+	rspi_write8(rspi, 0x00, RSPI_SPCKD);
+	rspi_write8(rspi, 0x00, RSPI_SSLND);
+	rspi_write8(rspi, 0x00, RSPI_SPND);
+
+	/* Sets parity, interrupt mask */
+	rspi_write8(rspi, 0x00, RSPI_SPCR2);
+
+	/* Sets SPCMD */
+	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
+		     RSPI_SPCMD0);
+
+	/* Sets RSPI mode */
+	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+
+	return 0;
+}
+
+/*
+ * functions for QSPI
+ */
+static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 {
 {
-	int tmp;
-	unsigned char spbr;
+	u16 spcmd;
+	int spbr;
+
+	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
+	rspi_write8(rspi, 0x00, RSPI_SPPCR);
+
+	/* Sets transfer bit rate */
+	spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz);
+	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
+
+	/* Sets number of frames to be used: 1 frame */
+	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+
+	/* Sets RSPCK, SSL, next-access delay value */
+	rspi_write8(rspi, 0x00, RSPI_SPCKD);
+	rspi_write8(rspi, 0x00, RSPI_SSLND);
+	rspi_write8(rspi, 0x00, RSPI_SPND);
+
+	/* Data Length Setting */
+	if (access_size == 8)
+		spcmd = SPCMD_SPB_8BIT;
+	else if (access_size == 16)
+		spcmd = SPCMD_SPB_16BIT;
+	else if (access_size == 32)
+		spcmd = SPCMD_SPB_32BIT;
+
+	spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SSLKP | SPCMD_SPNDEN;
+
+	/* Resets transfer data length */
+	rspi_write32(rspi, 0, QSPI_SPBMUL0);
+
+	/* Resets transmit and receive buffer */
+	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
+	/* Sets buffer to allow normal operation */
+	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
+
+	/* Sets SPCMD */
+	rspi_write16(rspi, spcmd, RSPI_SPCMD0);
 
 
-	tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1;
-	spbr = clamp(tmp, 0, 255);
+	/* Enables SPI function in a master mode */
+	rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR);
 
 
-	return spbr;
+	return 0;
 }
 }
 
 
+#define set_config_register(spi, n) spi->ops->set_config_register(spi, n)
+
 static void rspi_enable_irq(struct rspi_data *rspi, u8 enable)
 static void rspi_enable_irq(struct rspi_data *rspi, u8 enable)
 {
 {
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR);
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR);
@@ -220,54 +326,60 @@ static void rspi_negate_ssl(struct rspi_data *rspi)
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
 	rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR);
 }
 }
 
 
-static int rspi_set_config_register(struct rspi_data *rspi, int access_size)
+static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
+			 struct spi_transfer *t)
 {
 {
-	/* Sets output mode(CMOS) and MOSI signal(from previous transfer) */
-	rspi_write8(rspi, 0x00, RSPI_SPPCR);
-
-	/* Sets transfer bit rate */
-	rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR);
-
-	/* Sets number of frames to be used: 1 frame */
-	rspi_write8(rspi, 0x00, RSPI_SPDCR);
+	int remain = t->len;
+	u8 *data;
 
 
-	/* Sets RSPCK, SSL, next-access delay value */
-	rspi_write8(rspi, 0x00, RSPI_SPCKD);
-	rspi_write8(rspi, 0x00, RSPI_SSLND);
-	rspi_write8(rspi, 0x00, RSPI_SPND);
+	data = (u8 *)t->tx_buf;
+	while (remain > 0) {
+		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
+			    RSPI_SPCR);
 
 
-	/* Sets parity, interrupt mask */
-	rspi_write8(rspi, 0x00, RSPI_SPCR2);
+		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
+			dev_err(&rspi->master->dev,
+				"%s: tx empty timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
 
 
-	/* Sets SPCMD */
-	rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP,
-		     RSPI_SPCMD0);
+		rspi_write16(rspi, *data, RSPI_SPDR);
+		data++;
+		remain--;
+	}
 
 
-	/* Sets RSPI mode */
-	rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR);
+	/* Waiting for the last transmition */
+	rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
+static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 			 struct spi_transfer *t)
 			 struct spi_transfer *t)
 {
 {
 	int remain = t->len;
 	int remain = t->len;
 	u8 *data;
 	u8 *data;
 
 
+	rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR);
+	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
+
 	data = (u8 *)t->tx_buf;
 	data = (u8 *)t->tx_buf;
 	while (remain > 0) {
 	while (remain > 0) {
-		rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD,
-			    RSPI_SPCR);
 
 
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
 		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
 			dev_err(&rspi->master->dev,
 			dev_err(&rspi->master->dev,
 				"%s: tx empty timeout\n", __func__);
 				"%s: tx empty timeout\n", __func__);
 			return -ETIMEDOUT;
 			return -ETIMEDOUT;
 		}
 		}
+		rspi_write8(rspi, *data++, RSPI_SPDR);
+
+		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+			dev_err(&rspi->master->dev,
+				"%s: receive timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+		rspi_read8(rspi, RSPI_SPDR);
 
 
-		rspi_write16(rspi, *data, RSPI_SPDR);
-		data++;
 		remain--;
 		remain--;
 	}
 	}
 
 
@@ -277,6 +389,8 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 	return 0;
 }
 }
 
 
+#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t)
+
 static void rspi_dma_complete(void *arg)
 static void rspi_dma_complete(void *arg)
 {
 {
 	struct rspi_data *rspi = arg;
 	struct rspi_data *rspi = arg;
@@ -442,6 +556,51 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
 	return 0;
 	return 0;
 }
 }
 
 
+static void qspi_receive_init(struct rspi_data *rspi)
+{
+	unsigned char spsr;
+
+	spsr = rspi_read8(rspi, RSPI_SPSR);
+	if (spsr & SPSR_SPRF)
+		rspi_read8(rspi, RSPI_SPDR);   /* dummy read */
+	rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR);
+	rspi_write8(rspi, 0x00, QSPI_SPBFCR);
+}
+
+static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
+			    struct spi_transfer *t)
+{
+	int remain = t->len;
+	u8 *data;
+
+	qspi_receive_init(rspi);
+
+	data = (u8 *)t->rx_buf;
+	while (remain > 0) {
+
+		if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) {
+			dev_err(&rspi->master->dev,
+				"%s: tx empty timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+		/* dummy write for generate clock */
+		rspi_write8(rspi, 0x00, RSPI_SPDR);
+
+		if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) {
+			dev_err(&rspi->master->dev,
+				"%s: receive timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+		/* SPDR allows 8, 16 or 32-bit access */
+		*data++ = rspi_read8(rspi, RSPI_SPDR);
+		remain--;
+	}
+
+	return 0;
+}
+
+#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t)
+
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
 {
 {
 	struct scatterlist sg, sg_dummy;
 	struct scatterlist sg, sg_dummy;
@@ -581,7 +740,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_send_dma(rspi, t);
 					ret = rspi_send_dma(rspi, t);
 				else
 				else
-					ret = rspi_send_pio(rspi, mesg, t);
+					ret = send_pio(rspi, mesg, t);
 				if (ret < 0)
 				if (ret < 0)
 					goto error;
 					goto error;
 			}
 			}
@@ -589,7 +748,7 @@ static void rspi_work(struct work_struct *work)
 				if (rspi_is_dma(rspi, t))
 				if (rspi_is_dma(rspi, t))
 					ret = rspi_receive_dma(rspi, t);
 					ret = rspi_receive_dma(rspi, t);
 				else
 				else
-					ret = rspi_receive_pio(rspi, mesg, t);
+					ret = receive_pio(rspi, mesg, t);
 				if (ret < 0)
 				if (ret < 0)
 					goto error;
 					goto error;
 			}
 			}
@@ -616,7 +775,7 @@ static int rspi_setup(struct spi_device *spi)
 		spi->bits_per_word = 8;
 		spi->bits_per_word = 8;
 	rspi->max_speed_hz = spi->max_speed_hz;
 	rspi->max_speed_hz = spi->max_speed_hz;
 
 
-	rspi_set_config_register(rspi, 8);
+	set_config_register(rspi, 8);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -745,7 +904,16 @@ static int rspi_probe(struct platform_device *pdev)
 	struct rspi_data *rspi;
 	struct rspi_data *rspi;
 	int ret, irq;
 	int ret, irq;
 	char clk_name[16];
 	char clk_name[16];
-
+	struct rspi_plat_data *rspi_pd = pdev->dev.platform_data;
+	const struct spi_ops *ops;
+	const struct platform_device_id *id_entry = pdev->id_entry;
+
+	ops = (struct spi_ops *)id_entry->driver_data;
+	/* ops parameter check */
+	if (!ops->set_config_register) {
+		dev_err(&pdev->dev, "there is no set_config_register\n");
+		return -ENODEV;
+	}
 	/* get base addr */
 	/* get base addr */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (unlikely(res == NULL)) {
 	if (unlikely(res == NULL)) {
@@ -767,7 +935,7 @@ static int rspi_probe(struct platform_device *pdev)
 
 
 	rspi = spi_master_get_devdata(master);
 	rspi = spi_master_get_devdata(master);
 	platform_set_drvdata(pdev, rspi);
 	platform_set_drvdata(pdev, rspi);
-
+	rspi->ops = ops;
 	rspi->master = master;
 	rspi->master = master;
 	rspi->addr = ioremap(res->start, resource_size(res));
 	rspi->addr = ioremap(res->start, resource_size(res));
 	if (rspi->addr == NULL) {
 	if (rspi->addr == NULL) {
@@ -776,7 +944,7 @@ static int rspi_probe(struct platform_device *pdev)
 		goto error1;
 		goto error1;
 	}
 	}
 
 
-	snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id);
+	snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id);
 	rspi->clk = clk_get(&pdev->dev, clk_name);
 	rspi->clk = clk_get(&pdev->dev, clk_name);
 	if (IS_ERR(rspi->clk)) {
 	if (IS_ERR(rspi->clk)) {
 		dev_err(&pdev->dev, "cannot get clock\n");
 		dev_err(&pdev->dev, "cannot get clock\n");
@@ -790,7 +958,10 @@ static int rspi_probe(struct platform_device *pdev)
 	INIT_WORK(&rspi->ws, rspi_work);
 	INIT_WORK(&rspi->ws, rspi_work);
 	init_waitqueue_head(&rspi->wait);
 	init_waitqueue_head(&rspi->wait);
 
 
-	master->num_chipselect = 2;
+	master->num_chipselect = rspi_pd->num_chipselect;
+	if (!master->num_chipselect)
+		master->num_chipselect = 2; /* default */
+
 	master->bus_num = pdev->id;
 	master->bus_num = pdev->id;
 	master->setup = rspi_setup;
 	master->setup = rspi_setup;
 	master->transfer = rspi_transfer;
 	master->transfer = rspi_transfer;
@@ -832,11 +1003,32 @@ error1:
 	return ret;
 	return ret;
 }
 }
 
 
+static struct spi_ops rspi_ops = {
+	.set_config_register =		rspi_set_config_register,
+	.send_pio =			rspi_send_pio,
+	.receive_pio =			rspi_receive_pio,
+};
+
+static struct spi_ops qspi_ops = {
+	.set_config_register =		qspi_set_config_register,
+	.send_pio =			qspi_send_pio,
+	.receive_pio =			qspi_receive_pio,
+};
+
+static struct platform_device_id spi_driver_ids[] = {
+	{ "rspi",	(kernel_ulong_t)&rspi_ops },
+	{ "qspi",	(kernel_ulong_t)&qspi_ops },
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, spi_driver_ids);
+
 static struct platform_driver rspi_driver = {
 static struct platform_driver rspi_driver = {
 	.probe =	rspi_probe,
 	.probe =	rspi_probe,
 	.remove =	rspi_remove,
 	.remove =	rspi_remove,
+	.id_table =	spi_driver_ids,
 	.driver		= {
 	.driver		= {
-		.name = "rspi",
+		.name = "renesas_spi",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 };
 };

+ 2 - 2
drivers/spi/spi-s3c24xx.c

@@ -280,7 +280,7 @@ static inline u32 ack_bit(unsigned int irq)
  * so the caller does not need to do anything more than start the transfer
  * so the caller does not need to do anything more than start the transfer
  * as normal, since the IRQ will have been re-routed to the FIQ handler.
  * as normal, since the IRQ will have been re-routed to the FIQ handler.
 */
 */
-void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
+static void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw)
 {
 {
 	struct pt_regs regs;
 	struct pt_regs regs;
 	enum spi_fiq_mode mode;
 	enum spi_fiq_mode mode;
@@ -524,7 +524,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
 	hw = spi_master_get_devdata(master);
 	hw = spi_master_get_devdata(master);
 	memset(hw, 0, sizeof(struct s3c24xx_spi));
 	memset(hw, 0, sizeof(struct s3c24xx_spi));
 
 
-	hw->master = spi_master_get(master);
+	hw->master = master;
 	hw->pdata = pdata = dev_get_platdata(&pdev->dev);
 	hw->pdata = pdata = dev_get_platdata(&pdev->dev);
 	hw->dev = &pdev->dev;
 	hw->dev = &pdev->dev;
 
 

+ 126 - 134
drivers/spi/spi-s3c64xx.c

@@ -205,7 +205,6 @@ struct s3c64xx_spi_driver_data {
 #endif
 #endif
 	struct s3c64xx_spi_port_config	*port_conf;
 	struct s3c64xx_spi_port_config	*port_conf;
 	unsigned int			port_id;
 	unsigned int			port_id;
-	unsigned long			gpios[4];
 	bool				cs_gpio;
 	bool				cs_gpio;
 };
 };
 
 
@@ -559,25 +558,18 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
 static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
 static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
 						struct spi_device *spi)
 						struct spi_device *spi)
 {
 {
-	struct s3c64xx_spi_csinfo *cs;
-
 	if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */
 	if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */
 		if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
 		if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
 			/* Deselect the last toggled device */
 			/* Deselect the last toggled device */
-			cs = sdd->tgl_spi->controller_data;
-			if (sdd->cs_gpio)
-				gpio_set_value(cs->line,
+			if (spi->cs_gpio >= 0)
+				gpio_set_value(spi->cs_gpio,
 					spi->mode & SPI_CS_HIGH ? 0 : 1);
 					spi->mode & SPI_CS_HIGH ? 0 : 1);
 		}
 		}
 		sdd->tgl_spi = NULL;
 		sdd->tgl_spi = NULL;
 	}
 	}
 
 
-	cs = spi->controller_data;
-	if (sdd->cs_gpio)
-		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
-
-	/* Start the signals */
-	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (spi->cs_gpio >= 0)
+		gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 1 : 0);
 }
 }
 
 
 static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
 static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
@@ -702,16 +694,11 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
 static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
 static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
 						struct spi_device *spi)
 						struct spi_device *spi)
 {
 {
-	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
-
 	if (sdd->tgl_spi == spi)
 	if (sdd->tgl_spi == spi)
 		sdd->tgl_spi = NULL;
 		sdd->tgl_spi = NULL;
 
 
-	if (sdd->cs_gpio)
-		gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
-
-	/* Quiese the signals */
-	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
+	if (spi->cs_gpio >= 0)
+		gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
 }
 }
 
 
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
 static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
@@ -862,16 +849,12 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
 	}
 	}
 }
 }
 
 
-static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
-					    struct spi_message *msg)
+static int s3c64xx_spi_prepare_message(struct spi_master *master,
+				       struct spi_message *msg)
 {
 {
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	struct spi_device *spi = msg->spi;
 	struct spi_device *spi = msg->spi;
 	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
 	struct s3c64xx_spi_csinfo *cs = spi->controller_data;
-	struct spi_transfer *xfer;
-	int status = 0, cs_toggle = 0;
-	u32 speed;
-	u8 bpw;
 
 
 	/* If Master's(controller) state differs from that needed by Slave */
 	/* If Master's(controller) state differs from that needed by Slave */
 	if (sdd->cur_speed != spi->max_speed_hz
 	if (sdd->cur_speed != spi->max_speed_hz
@@ -887,106 +870,98 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
 	if (s3c64xx_spi_map_mssg(sdd, msg)) {
 	if (s3c64xx_spi_map_mssg(sdd, msg)) {
 		dev_err(&spi->dev,
 		dev_err(&spi->dev,
 			"Xfer: Unable to map message buffers!\n");
 			"Xfer: Unable to map message buffers!\n");
-		status = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 	}
 
 
 	/* Configure feedback delay */
 	/* Configure feedback delay */
 	writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
 	writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK);
 
 
-	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-
-		unsigned long flags;
-		int use_dma;
-
-		INIT_COMPLETION(sdd->xfer_completion);
-
-		/* Only BPW and Speed may change across transfers */
-		bpw = xfer->bits_per_word;
-		speed = xfer->speed_hz ? : spi->max_speed_hz;
-
-		if (xfer->len % (bpw / 8)) {
-			dev_err(&spi->dev,
-				"Xfer length(%u) not a multiple of word size(%u)\n",
-				xfer->len, bpw / 8);
-			status = -EIO;
-			goto out;
-		}
+	return 0;
+}
 
 
-		if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
-			sdd->cur_bpw = bpw;
-			sdd->cur_speed = speed;
-			s3c64xx_spi_config(sdd);
-		}
+static int s3c64xx_spi_transfer_one(struct spi_master *master,
+				    struct spi_device *spi,
+				    struct spi_transfer *xfer)
+{
+	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
+	int status;
+	u32 speed;
+	u8 bpw;
+	unsigned long flags;
+	int use_dma;
 
 
-		/* Polling method for xfers not bigger than FIFO capacity */
-		use_dma = 0;
-		if (!is_polling(sdd) &&
-			(sdd->rx_dma.ch && sdd->tx_dma.ch &&
-			(xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))))
-			use_dma = 1;
+	INIT_COMPLETION(sdd->xfer_completion);
 
 
-		spin_lock_irqsave(&sdd->lock, flags);
+	/* Only BPW and Speed may change across transfers */
+	bpw = xfer->bits_per_word;
+	speed = xfer->speed_hz ? : spi->max_speed_hz;
 
 
-		/* Pending only which is to be done */
-		sdd->state &= ~RXBUSY;
-		sdd->state &= ~TXBUSY;
+	if (xfer->len % (bpw / 8)) {
+		dev_err(&spi->dev,
+			"Xfer length(%u) not a multiple of word size(%u)\n",
+			xfer->len, bpw / 8);
+		return -EIO;
+	}
 
 
-		enable_datapath(sdd, spi, xfer, use_dma);
+	if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
+		sdd->cur_bpw = bpw;
+		sdd->cur_speed = speed;
+		s3c64xx_spi_config(sdd);
+	}
 
 
-		/* Slave Select */
-		enable_cs(sdd, spi);
+	/* Polling method for xfers not bigger than FIFO capacity */
+	use_dma = 0;
+	if (!is_polling(sdd) &&
+	    (sdd->rx_dma.ch && sdd->tx_dma.ch &&
+	     (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1))))
+		use_dma = 1;
 
 
-		spin_unlock_irqrestore(&sdd->lock, flags);
+	spin_lock_irqsave(&sdd->lock, flags);
 
 
-		status = wait_for_xfer(sdd, xfer, use_dma);
+	/* Pending only which is to be done */
+	sdd->state &= ~RXBUSY;
+	sdd->state &= ~TXBUSY;
 
 
-		if (status) {
-			dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
-				xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
-				(sdd->state & RXBUSY) ? 'f' : 'p',
-				(sdd->state & TXBUSY) ? 'f' : 'p',
-				xfer->len);
+	enable_datapath(sdd, spi, xfer, use_dma);
 
 
-			if (use_dma) {
-				if (xfer->tx_buf != NULL
-						&& (sdd->state & TXBUSY))
-					s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma);
-				if (xfer->rx_buf != NULL
-						&& (sdd->state & RXBUSY))
-					s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma);
-			}
+	/* Start the signals */
+	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
 
-			goto out;
-		}
+	/* Start the signals */
+	writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 
 
-		if (xfer->delay_usecs)
-			udelay(xfer->delay_usecs);
+	spin_unlock_irqrestore(&sdd->lock, flags);
 
 
-		if (xfer->cs_change) {
-			/* Hint that the next mssg is gonna be
-			   for the same device */
-			if (list_is_last(&xfer->transfer_list,
-						&msg->transfers))
-				cs_toggle = 1;
+	status = wait_for_xfer(sdd, xfer, use_dma);
+
+	if (status) {
+		dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",
+			xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0,
+			(sdd->state & RXBUSY) ? 'f' : 'p',
+			(sdd->state & TXBUSY) ? 'f' : 'p',
+			xfer->len);
+
+		if (use_dma) {
+			if (xfer->tx_buf != NULL
+			    && (sdd->state & TXBUSY))
+				s3c64xx_spi_dma_stop(sdd, &sdd->tx_dma);
+			if (xfer->rx_buf != NULL
+			    && (sdd->state & RXBUSY))
+				s3c64xx_spi_dma_stop(sdd, &sdd->rx_dma);
 		}
 		}
-
-		msg->actual_length += xfer->len;
-
+	} else {
 		flush_fifo(sdd);
 		flush_fifo(sdd);
 	}
 	}
 
 
-out:
-	if (!cs_toggle || status)
-		disable_cs(sdd, spi);
-	else
-		sdd->tgl_spi = spi;
-
-	s3c64xx_spi_unmap_mssg(sdd, msg);
+	return status;
+}
 
 
-	msg->status = status;
+static int s3c64xx_spi_unprepare_message(struct spi_master *master,
+					    struct spi_message *msg)
+{
+	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 
 
-	spi_finalize_current_message(master);
+	s3c64xx_spi_unmap_mssg(sdd, msg);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1071,6 +1046,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
 					cs->line, err);
 					cs->line, err);
 				goto err_gpio_req;
 				goto err_gpio_req;
 			}
 			}
+
+			spi->cs_gpio = cs->line;
 		}
 		}
 
 
 		spi_set_ctldata(spi, cs);
 		spi_set_ctldata(spi, cs);
@@ -1117,11 +1094,14 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
 	}
 	}
 
 
 	pm_runtime_put(&sdd->pdev->dev);
 	pm_runtime_put(&sdd->pdev->dev);
+	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 	disable_cs(sdd, spi);
 	disable_cs(sdd, spi);
 	return 0;
 	return 0;
 
 
 setup_exit:
 setup_exit:
+	pm_runtime_put(&sdd->pdev->dev);
 	/* setup() returns with device de-selected */
 	/* setup() returns with device de-selected */
+	writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
 	disable_cs(sdd, spi);
 	disable_cs(sdd, spi);
 
 
 	gpio_free(cs->line);
 	gpio_free(cs->line);
@@ -1140,8 +1120,8 @@ static void s3c64xx_spi_cleanup(struct spi_device *spi)
 	struct s3c64xx_spi_driver_data *sdd;
 	struct s3c64xx_spi_driver_data *sdd;
 
 
 	sdd = spi_master_get_devdata(spi->master);
 	sdd = spi_master_get_devdata(spi->master);
-	if (cs && sdd->cs_gpio) {
-		gpio_free(cs->line);
+	if (spi->cs_gpio) {
+		gpio_free(spi->cs_gpio);
 		if (spi->dev.of_node)
 		if (spi->dev.of_node)
 			kfree(cs);
 			kfree(cs);
 	}
 	}
@@ -1359,7 +1339,9 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	master->setup = s3c64xx_spi_setup;
 	master->setup = s3c64xx_spi_setup;
 	master->cleanup = s3c64xx_spi_cleanup;
 	master->cleanup = s3c64xx_spi_cleanup;
 	master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
 	master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
-	master->transfer_one_message = s3c64xx_spi_transfer_one_message;
+	master->prepare_message = s3c64xx_spi_prepare_message;
+	master->transfer_one = s3c64xx_spi_transfer_one;
+	master->unprepare_message = s3c64xx_spi_unprepare_message;
 	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
 	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
 	master->num_chipselect = sci->num_cs;
 	master->num_chipselect = sci->num_cs;
 	master->dma_alignment = 8;
 	master->dma_alignment = 8;
@@ -1428,11 +1410,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 	       S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
 	       S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
 	       sdd->regs + S3C64XX_SPI_INT_EN);
 	       sdd->regs + S3C64XX_SPI_INT_EN);
 
 
+	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 
 
-	if (spi_register_master(master)) {
-		dev_err(&pdev->dev, "cannot register SPI master\n");
-		ret = -EBUSY;
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);
 		goto err3;
 		goto err3;
 	}
 	}
 
 
@@ -1461,16 +1444,12 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
 
 
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 
-	spi_unregister_master(master);
-
 	writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
 	writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
 
 
 	clk_disable_unprepare(sdd->src_clk);
 	clk_disable_unprepare(sdd->src_clk);
 
 
 	clk_disable_unprepare(sdd->clk);
 	clk_disable_unprepare(sdd->clk);
 
 
-	spi_master_put(master);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1480,11 +1459,14 @@ static int s3c64xx_spi_suspend(struct device *dev)
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 
 
-	spi_master_suspend(master);
+	int ret = spi_master_suspend(master);
+	if (ret)
+		return ret;
 
 
-	/* Disable the clock */
-	clk_disable_unprepare(sdd->src_clk);
-	clk_disable_unprepare(sdd->clk);
+	if (!pm_runtime_suspended(dev)) {
+		clk_disable_unprepare(sdd->clk);
+		clk_disable_unprepare(sdd->src_clk);
+	}
 
 
 	sdd->cur_speed = 0; /* Output Clock is stopped */
 	sdd->cur_speed = 0; /* Output Clock is stopped */
 
 
@@ -1500,15 +1482,14 @@ static int s3c64xx_spi_resume(struct device *dev)
 	if (sci->cfg_gpio)
 	if (sci->cfg_gpio)
 		sci->cfg_gpio();
 		sci->cfg_gpio();
 
 
-	/* Enable the clock */
-	clk_prepare_enable(sdd->src_clk);
-	clk_prepare_enable(sdd->clk);
+	if (!pm_runtime_suspended(dev)) {
+		clk_prepare_enable(sdd->src_clk);
+		clk_prepare_enable(sdd->clk);
+	}
 
 
 	s3c64xx_spi_hwinit(sdd, sdd->port_id);
 	s3c64xx_spi_hwinit(sdd, sdd->port_id);
 
 
-	spi_master_resume(master);
-
-	return 0;
+	return spi_master_resume(master);
 }
 }
 #endif /* CONFIG_PM_SLEEP */
 #endif /* CONFIG_PM_SLEEP */
 
 
@@ -1528,9 +1509,17 @@ static int s3c64xx_spi_runtime_resume(struct device *dev)
 {
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
+	int ret;
 
 
-	clk_prepare_enable(sdd->src_clk);
-	clk_prepare_enable(sdd->clk);
+	ret = clk_prepare_enable(sdd->src_clk);
+	if (ret != 0)
+		return ret;
+
+	ret = clk_prepare_enable(sdd->clk);
+	if (ret != 0) {
+		clk_disable_unprepare(sdd->src_clk);
+		return ret;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1616,6 +1605,18 @@ static struct platform_device_id s3c64xx_spi_driver_ids[] = {
 };
 };
 
 
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
 static const struct of_device_id s3c64xx_spi_dt_match[] = {
+	{ .compatible = "samsung,s3c2443-spi",
+			.data = (void *)&s3c2443_spi_port_config,
+	},
+	{ .compatible = "samsung,s3c6410-spi",
+			.data = (void *)&s3c6410_spi_port_config,
+	},
+	{ .compatible = "samsung,s5pc100-spi",
+			.data = (void *)&s5pc100_spi_port_config,
+	},
+	{ .compatible = "samsung,s5pv210-spi",
+			.data = (void *)&s5pv210_spi_port_config,
+	},
 	{ .compatible = "samsung,exynos4210-spi",
 	{ .compatible = "samsung,exynos4210-spi",
 			.data = (void *)&exynos4_spi_port_config,
 			.data = (void *)&exynos4_spi_port_config,
 	},
 	},
@@ -1633,22 +1634,13 @@ static struct platform_driver s3c64xx_spi_driver = {
 		.pm = &s3c64xx_spi_pm,
 		.pm = &s3c64xx_spi_pm,
 		.of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
 		.of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
 	},
 	},
+	.probe = s3c64xx_spi_probe,
 	.remove = s3c64xx_spi_remove,
 	.remove = s3c64xx_spi_remove,
 	.id_table = s3c64xx_spi_driver_ids,
 	.id_table = s3c64xx_spi_driver_ids,
 };
 };
 MODULE_ALIAS("platform:s3c64xx-spi");
 MODULE_ALIAS("platform:s3c64xx-spi");
 
 
-static int __init s3c64xx_spi_init(void)
-{
-	return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe);
-}
-subsys_initcall(s3c64xx_spi_init);
-
-static void __exit s3c64xx_spi_exit(void)
-{
-	platform_driver_unregister(&s3c64xx_spi_driver);
-}
-module_exit(s3c64xx_spi_exit);
+module_platform_driver(s3c64xx_spi_driver);
 
 
 MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
 MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");
 MODULE_DESCRIPTION("S3C64XX SPI Controller Driver");

+ 10 - 3
drivers/spi/spi-sh-hspi.c

@@ -137,7 +137,7 @@ static void hspi_hw_setup(struct hspi_priv *hspi,
 			rate /= 16;
 			rate /= 16;
 
 
 		/* CLKCx calculation */
 		/* CLKCx calculation */
-		rate /= (((idiv_clk & 0x1F) + 1) * 2) ;
+		rate /= (((idiv_clk & 0x1F) + 1) * 2);
 
 
 		/* save best settings */
 		/* save best settings */
 		tmp = abs(target_rate - rate);
 		tmp = abs(target_rate - rate);
@@ -303,9 +303,10 @@ static int hspi_probe(struct platform_device *pdev)
 	master->setup		= hspi_setup;
 	master->setup		= hspi_setup;
 	master->cleanup		= hspi_cleanup;
 	master->cleanup		= hspi_cleanup;
 	master->mode_bits	= SPI_CPOL | SPI_CPHA;
 	master->mode_bits	= SPI_CPOL | SPI_CPHA;
+	master->dev.of_node	= pdev->dev.of_node;
 	master->auto_runtime_pm = true;
 	master->auto_runtime_pm = true;
 	master->transfer_one_message		= hspi_transfer_one_message;
 	master->transfer_one_message		= hspi_transfer_one_message;
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "spi_register_master error.\n");
 		dev_err(&pdev->dev, "spi_register_master error.\n");
 		goto error1;
 		goto error1;
@@ -328,17 +329,23 @@ static int hspi_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
 
 	clk_put(hspi->clk);
 	clk_put(hspi->clk);
-	spi_unregister_master(hspi->master);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static struct of_device_id hspi_of_match[] = {
+	{ .compatible = "renesas,hspi", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, hspi_of_match);
+
 static struct platform_driver hspi_driver = {
 static struct platform_driver hspi_driver = {
 	.probe = hspi_probe,
 	.probe = hspi_probe,
 	.remove = hspi_remove,
 	.remove = hspi_remove,
 	.driver = {
 	.driver = {
 		.name = "sh-hspi",
 		.name = "sh-hspi",
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,
+		.of_match_table = hspi_of_match,
 	},
 	},
 };
 };
 module_platform_driver(hspi_driver);
 module_platform_driver(hspi_driver);

+ 1 - 1
drivers/spi/spi-sh-sci.c

@@ -133,7 +133,7 @@ static int sh_sci_spi_probe(struct platform_device *dev)
 	sp->info = dev_get_platdata(&dev->dev);
 	sp->info = dev_get_platdata(&dev->dev);
 
 
 	/* setup spi bitbang adaptor */
 	/* setup spi bitbang adaptor */
-	sp->bitbang.master = spi_master_get(master);
+	sp->bitbang.master = master;
 	sp->bitbang.master->bus_num = sp->info->bus_num;
 	sp->bitbang.master->bus_num = sp->info->bus_num;
 	sp->bitbang.master->num_chipselect = sp->info->num_chipselect;
 	sp->bitbang.master->num_chipselect = sp->info->num_chipselect;
 	sp->bitbang.chipselect = sh_sci_spi_chipselect;
 	sp->bitbang.chipselect = sh_sci_spi_chipselect;

+ 1 - 1
drivers/spi/spi-sirf.c

@@ -632,7 +632,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
 	if (ret)
 	if (ret)
 		goto free_master;
 		goto free_master;
 
 
-	sspi->bitbang.master = spi_master_get(master);
+	sspi->bitbang.master = master;
 	sspi->bitbang.chipselect = spi_sirfsoc_chipselect;
 	sspi->bitbang.chipselect = spi_sirfsoc_chipselect;
 	sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer;
 	sspi->bitbang.setup_transfer = spi_sirfsoc_setup_transfer;
 	sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer;
 	sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer;

+ 70 - 20
drivers/spi/spi-tegra114.c

@@ -182,6 +182,7 @@ struct tegra_spi_data {
 	u32					cur_speed;
 	u32					cur_speed;
 
 
 	struct spi_device			*cur_spi;
 	struct spi_device			*cur_spi;
+	struct spi_device			*cs_control;
 	unsigned				cur_pos;
 	unsigned				cur_pos;
 	unsigned				cur_len;
 	unsigned				cur_len;
 	unsigned				words_per_32bit;
 	unsigned				words_per_32bit;
@@ -267,7 +268,7 @@ static unsigned tegra_spi_calculate_curr_xfer_param(
 	unsigned max_len;
 	unsigned max_len;
 	unsigned total_fifo_words;
 	unsigned total_fifo_words;
 
 
-	tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1;
+	tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
 
 
 	if (bits_per_word == 8 || bits_per_word == 16) {
 	if (bits_per_word == 8 || bits_per_word == 16) {
 		tspi->is_packed = 1;
 		tspi->is_packed = 1;
@@ -676,15 +677,12 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
 	dma_release_channel(dma_chan);
 	dma_release_channel(dma_chan);
 }
 }
 
 
-static int tegra_spi_start_transfer_one(struct spi_device *spi,
-		struct spi_transfer *t, bool is_first_of_msg,
-		bool is_single_xfer)
+static unsigned long tegra_spi_setup_transfer_one(struct spi_device *spi,
+		struct spi_transfer *t, bool is_first_of_msg)
 {
 {
 	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
 	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
 	u32 speed = t->speed_hz;
 	u32 speed = t->speed_hz;
 	u8 bits_per_word = t->bits_per_word;
 	u8 bits_per_word = t->bits_per_word;
-	unsigned total_fifo_words;
-	int ret;
 	unsigned long command1;
 	unsigned long command1;
 	int req_mode;
 	int req_mode;
 
 
@@ -698,7 +696,6 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
 	tspi->cur_rx_pos = 0;
 	tspi->cur_rx_pos = 0;
 	tspi->cur_tx_pos = 0;
 	tspi->cur_tx_pos = 0;
 	tspi->curr_xfer = t;
 	tspi->curr_xfer = t;
-	total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);
 
 
 	if (is_first_of_msg) {
 	if (is_first_of_msg) {
 		tegra_spi_clear_status(tspi);
 		tegra_spi_clear_status(tspi);
@@ -717,7 +714,12 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
 		else if (req_mode == SPI_MODE_3)
 		else if (req_mode == SPI_MODE_3)
 			command1 |= SPI_CONTROL_MODE_3;
 			command1 |= SPI_CONTROL_MODE_3;
 
 
-		tegra_spi_writel(tspi, command1, SPI_COMMAND1);
+		if (tspi->cs_control) {
+			if (tspi->cs_control != spi)
+				tegra_spi_writel(tspi, command1, SPI_COMMAND1);
+			tspi->cs_control = NULL;
+		} else
+			tegra_spi_writel(tspi, command1, SPI_COMMAND1);
 
 
 		command1 |= SPI_CS_SW_HW;
 		command1 |= SPI_CS_SW_HW;
 		if (spi->mode & SPI_CS_HIGH)
 		if (spi->mode & SPI_CS_HIGH)
@@ -732,6 +734,18 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
 		command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
 		command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
 	}
 	}
 
 
+	return command1;
+}
+
+static int tegra_spi_start_transfer_one(struct spi_device *spi,
+		struct spi_transfer *t, unsigned long command1)
+{
+	struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
+	unsigned total_fifo_words;
+	int ret;
+
+	total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);
+
 	if (tspi->is_packed)
 	if (tspi->is_packed)
 		command1 |= SPI_PACKED;
 		command1 |= SPI_PACKED;
 
 
@@ -803,29 +817,50 @@ static int tegra_spi_setup(struct spi_device *spi)
 	return 0;
 	return 0;
 }
 }
 
 
+static void tegra_spi_transfer_delay(int delay)
+{
+	if (!delay)
+		return;
+
+	if (delay >= 1000)
+		mdelay(delay / 1000);
+
+	udelay(delay % 1000);
+}
+
 static int tegra_spi_transfer_one_message(struct spi_master *master,
 static int tegra_spi_transfer_one_message(struct spi_master *master,
 			struct spi_message *msg)
 			struct spi_message *msg)
 {
 {
 	bool is_first_msg = true;
 	bool is_first_msg = true;
-	int single_xfer;
 	struct tegra_spi_data *tspi = spi_master_get_devdata(master);
 	struct tegra_spi_data *tspi = spi_master_get_devdata(master);
 	struct spi_transfer *xfer;
 	struct spi_transfer *xfer;
 	struct spi_device *spi = msg->spi;
 	struct spi_device *spi = msg->spi;
 	int ret;
 	int ret;
+	bool skip = false;
 
 
 	msg->status = 0;
 	msg->status = 0;
 	msg->actual_length = 0;
 	msg->actual_length = 0;
 
 
-	single_xfer = list_is_singular(&msg->transfers);
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		unsigned long cmd1;
+
 		INIT_COMPLETION(tspi->xfer_completion);
 		INIT_COMPLETION(tspi->xfer_completion);
-		ret = tegra_spi_start_transfer_one(spi, xfer,
-					is_first_msg, single_xfer);
+
+		cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg);
+
+		if (!xfer->len) {
+			ret = 0;
+			skip = true;
+			goto complete_xfer;
+		}
+
+		ret = tegra_spi_start_transfer_one(spi, xfer, cmd1);
 		if (ret < 0) {
 		if (ret < 0) {
 			dev_err(tspi->dev,
 			dev_err(tspi->dev,
 				"spi can not start transfer, err %d\n", ret);
 				"spi can not start transfer, err %d\n", ret);
-			goto exit;
+			goto complete_xfer;
 		}
 		}
+
 		is_first_msg = false;
 		is_first_msg = false;
 		ret = wait_for_completion_timeout(&tspi->xfer_completion,
 		ret = wait_for_completion_timeout(&tspi->xfer_completion,
 						SPI_DMA_TIMEOUT);
 						SPI_DMA_TIMEOUT);
@@ -833,24 +868,40 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
 			dev_err(tspi->dev,
 			dev_err(tspi->dev,
 				"spi trasfer timeout, err %d\n", ret);
 				"spi trasfer timeout, err %d\n", ret);
 			ret = -EIO;
 			ret = -EIO;
-			goto exit;
+			goto complete_xfer;
 		}
 		}
 
 
 		if (tspi->tx_status ||  tspi->rx_status) {
 		if (tspi->tx_status ||  tspi->rx_status) {
 			dev_err(tspi->dev, "Error in Transfer\n");
 			dev_err(tspi->dev, "Error in Transfer\n");
 			ret = -EIO;
 			ret = -EIO;
-			goto exit;
+			goto complete_xfer;
 		}
 		}
 		msg->actual_length += xfer->len;
 		msg->actual_length += xfer->len;
-		if (xfer->cs_change && xfer->delay_usecs) {
+
+complete_xfer:
+		if (ret < 0 || skip) {
 			tegra_spi_writel(tspi, tspi->def_command1_reg,
 			tegra_spi_writel(tspi, tspi->def_command1_reg,
 					SPI_COMMAND1);
 					SPI_COMMAND1);
-			udelay(xfer->delay_usecs);
+			tegra_spi_transfer_delay(xfer->delay_usecs);
+			goto exit;
+		} else if (msg->transfers.prev == &xfer->transfer_list) {
+			/* This is the last transfer in message */
+			if (xfer->cs_change)
+				tspi->cs_control = spi;
+			else {
+				tegra_spi_writel(tspi, tspi->def_command1_reg,
+						SPI_COMMAND1);
+				tegra_spi_transfer_delay(xfer->delay_usecs);
+			}
+		} else if (xfer->cs_change) {
+			tegra_spi_writel(tspi, tspi->def_command1_reg,
+					SPI_COMMAND1);
+			tegra_spi_transfer_delay(xfer->delay_usecs);
 		}
 		}
+
 	}
 	}
 	ret = 0;
 	ret = 0;
 exit:
 exit:
-	tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
 	msg->status = ret;
 	msg->status = ret;
 	spi_finalize_current_message(master);
 	spi_finalize_current_message(master);
 	return ret;
 	return ret;
@@ -1115,7 +1166,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_put(&pdev->dev);
 
 
 	master->dev.of_node = pdev->dev.of_node;
 	master->dev.of_node = pdev->dev.of_node;
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		goto exit_pm_disable;
 		goto exit_pm_disable;
@@ -1142,7 +1193,6 @@ static int tegra_spi_remove(struct platform_device *pdev)
 	struct tegra_spi_data	*tspi = spi_master_get_devdata(master);
 	struct tegra_spi_data	*tspi = spi_master_get_devdata(master);
 
 
 	free_irq(tspi->irq, tspi);
 	free_irq(tspi->irq, tspi);
-	spi_unregister_master(master);
 
 
 	if (tspi->tx_dma_chan)
 	if (tspi->tx_dma_chan)
 		tegra_spi_deinit_dma_param(tspi, false);
 		tegra_spi_deinit_dma_param(tspi, false);

+ 2 - 3
drivers/spi/spi-tegra20-sflash.c

@@ -173,7 +173,7 @@ static unsigned tegra_sflash_calculate_curr_xfer_param(
 	unsigned remain_len = t->len - tsd->cur_pos;
 	unsigned remain_len = t->len - tsd->cur_pos;
 	unsigned max_word;
 	unsigned max_word;
 
 
-	tsd->bytes_per_word = (t->bits_per_word - 1) / 8 + 1;
+	tsd->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);
 	max_word = remain_len / tsd->bytes_per_word;
 	max_word = remain_len / tsd->bytes_per_word;
 	if (max_word > SPI_FIFO_DEPTH)
 	if (max_word > SPI_FIFO_DEPTH)
 		max_word = SPI_FIFO_DEPTH;
 		max_word = SPI_FIFO_DEPTH;
@@ -529,7 +529,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_put(&pdev->dev);
 
 
 	master->dev.of_node = pdev->dev.of_node;
 	master->dev.of_node = pdev->dev.of_node;
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		goto exit_pm_disable;
 		goto exit_pm_disable;
@@ -553,7 +553,6 @@ static int tegra_sflash_remove(struct platform_device *pdev)
 	struct tegra_sflash_data	*tsd = spi_master_get_devdata(master);
 	struct tegra_sflash_data	*tsd = spi_master_get_devdata(master);
 
 
 	free_irq(tsd->irq, tsd);
 	free_irq(tsd->irq, tsd);
-	spi_unregister_master(master);
 
 
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	if (!pm_runtime_status_suspended(&pdev->dev))
 	if (!pm_runtime_status_suspended(&pdev->dev))

+ 69 - 75
drivers/spi/spi-tegra20-slink.c

@@ -278,12 +278,12 @@ static unsigned tegra_slink_calculate_curr_xfer_param(
 {
 {
 	unsigned remain_len = t->len - tspi->cur_pos;
 	unsigned remain_len = t->len - tspi->cur_pos;
 	unsigned max_word;
 	unsigned max_word;
-	unsigned bits_per_word ;
+	unsigned bits_per_word;
 	unsigned max_len;
 	unsigned max_len;
 	unsigned total_fifo_words;
 	unsigned total_fifo_words;
 
 
 	bits_per_word = t->bits_per_word;
 	bits_per_word = t->bits_per_word;
-	tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1;
+	tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8);
 
 
 	if (bits_per_word == 8 || bits_per_word == 16) {
 	if (bits_per_word == 8 || bits_per_word == 16) {
 		tspi->is_packed = 1;
 		tspi->is_packed = 1;
@@ -707,8 +707,7 @@ static void tegra_slink_deinit_dma_param(struct tegra_slink_data *tspi,
 }
 }
 
 
 static int tegra_slink_start_transfer_one(struct spi_device *spi,
 static int tegra_slink_start_transfer_one(struct spi_device *spi,
-		struct spi_transfer *t, bool is_first_of_msg,
-		bool is_single_xfer)
+		struct spi_transfer *t)
 {
 {
 	struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
 	struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
 	u32 speed;
 	u32 speed;
@@ -732,32 +731,12 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
 	tspi->curr_xfer = t;
 	tspi->curr_xfer = t;
 	total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t);
 	total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t);
 
 
-	if (is_first_of_msg) {
-		tegra_slink_clear_status(tspi);
+	command = tspi->command_reg;
+	command &= ~SLINK_BIT_LENGTH(~0);
+	command |= SLINK_BIT_LENGTH(bits_per_word - 1);
 
 
-		command = tspi->def_command_reg;
-		command |= SLINK_BIT_LENGTH(bits_per_word - 1);
-		command |= SLINK_CS_SW | SLINK_CS_VALUE;
-
-		command2 = tspi->def_command2_reg;
-		command2 |= SLINK_SS_EN_CS(spi->chip_select);
-
-		command &= ~SLINK_MODES;
-		if (spi->mode & SPI_CPHA)
-			command |= SLINK_CK_SDA;
-
-		if (spi->mode & SPI_CPOL)
-			command |= SLINK_IDLE_SCLK_DRIVE_HIGH;
-		else
-			command |= SLINK_IDLE_SCLK_DRIVE_LOW;
-	} else {
-		command = tspi->command_reg;
-		command &= ~SLINK_BIT_LENGTH(~0);
-		command |= SLINK_BIT_LENGTH(bits_per_word - 1);
-
-		command2 = tspi->command2_reg;
-		command2 &= ~(SLINK_RXEN | SLINK_TXEN);
-	}
+	command2 = tspi->command2_reg;
+	command2 &= ~(SLINK_RXEN | SLINK_TXEN);
 
 
 	tegra_slink_writel(tspi, command, SLINK_COMMAND);
 	tegra_slink_writel(tspi, command, SLINK_COMMAND);
 	tspi->command_reg = command;
 	tspi->command_reg = command;
@@ -824,58 +803,72 @@ static int tegra_slink_setup(struct spi_device *spi)
 	return 0;
 	return 0;
 }
 }
 
 
-static int tegra_slink_transfer_one_message(struct spi_master *master,
-			struct spi_message *msg)
+static int tegra_slink_prepare_message(struct spi_master *master,
+				       struct spi_message *msg)
 {
 {
-	bool is_first_msg = true;
-	int single_xfer;
 	struct tegra_slink_data *tspi = spi_master_get_devdata(master);
 	struct tegra_slink_data *tspi = spi_master_get_devdata(master);
-	struct spi_transfer *xfer;
 	struct spi_device *spi = msg->spi;
 	struct spi_device *spi = msg->spi;
-	int ret;
 
 
-	msg->status = 0;
-	msg->actual_length = 0;
+	tegra_slink_clear_status(tspi);
 
 
-	single_xfer = list_is_singular(&msg->transfers);
-	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-		INIT_COMPLETION(tspi->xfer_completion);
-		ret = tegra_slink_start_transfer_one(spi, xfer,
-					is_first_msg, single_xfer);
-		if (ret < 0) {
-			dev_err(tspi->dev,
-				"spi can not start transfer, err %d\n", ret);
-			goto exit;
-		}
-		is_first_msg = false;
-		ret = wait_for_completion_timeout(&tspi->xfer_completion,
-						SLINK_DMA_TIMEOUT);
-		if (WARN_ON(ret == 0)) {
-			dev_err(tspi->dev,
-				"spi trasfer timeout, err %d\n", ret);
-			ret = -EIO;
-			goto exit;
-		}
+	tspi->command_reg = tspi->def_command_reg;
+	tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE;
 
 
-		if (tspi->tx_status ||  tspi->rx_status) {
-			dev_err(tspi->dev, "Error in Transfer\n");
-			ret = -EIO;
-			goto exit;
-		}
-		msg->actual_length += xfer->len;
-		if (xfer->cs_change && xfer->delay_usecs) {
-			tegra_slink_writel(tspi, tspi->def_command_reg,
-					SLINK_COMMAND);
-			udelay(xfer->delay_usecs);
-		}
+	tspi->command2_reg = tspi->def_command2_reg;
+	tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select);
+
+	tspi->command_reg &= ~SLINK_MODES;
+	if (spi->mode & SPI_CPHA)
+		tspi->command_reg |= SLINK_CK_SDA;
+
+	if (spi->mode & SPI_CPOL)
+		tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_HIGH;
+	else
+		tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_LOW;
+
+	return 0;
+}
+
+static int tegra_slink_transfer_one(struct spi_master *master,
+				    struct spi_device *spi,
+				    struct spi_transfer *xfer)
+{
+	struct tegra_slink_data *tspi = spi_master_get_devdata(master);
+	int ret;
+
+	INIT_COMPLETION(tspi->xfer_completion);
+	ret = tegra_slink_start_transfer_one(spi, xfer);
+	if (ret < 0) {
+		dev_err(tspi->dev,
+			"spi can not start transfer, err %d\n", ret);
+		return ret;
 	}
 	}
-	ret = 0;
-exit:
+
+	ret = wait_for_completion_timeout(&tspi->xfer_completion,
+					  SLINK_DMA_TIMEOUT);
+	if (WARN_ON(ret == 0)) {
+		dev_err(tspi->dev,
+			"spi trasfer timeout, err %d\n", ret);
+		return -EIO;
+	}
+
+	if (tspi->tx_status)
+		return tspi->tx_status;
+	if (tspi->rx_status)
+		return tspi->rx_status;
+
+	return 0;
+}
+
+static int tegra_slink_unprepare_message(struct spi_master *master,
+					 struct spi_message *msg)
+{
+	struct tegra_slink_data *tspi = spi_master_get_devdata(master);
+
 	tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND);
 	tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND);
 	tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2);
 	tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2);
-	msg->status = ret;
-	spi_finalize_current_message(master);
-	return ret;
+
+	return 0;
 }
 }
 
 
 static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
 static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi)
@@ -1078,7 +1071,9 @@ static int tegra_slink_probe(struct platform_device *pdev)
 	/* the spi->mode bits understood by this driver: */
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 	master->setup = tegra_slink_setup;
 	master->setup = tegra_slink_setup;
-	master->transfer_one_message = tegra_slink_transfer_one_message;
+	master->prepare_message = tegra_slink_prepare_message;
+	master->transfer_one = tegra_slink_transfer_one;
+	master->unprepare_message = tegra_slink_unprepare_message;
 	master->auto_runtime_pm = true;
 	master->auto_runtime_pm = true;
 	master->num_chipselect = MAX_CHIP_SELECT;
 	master->num_chipselect = MAX_CHIP_SELECT;
 	master->bus_num = -1;
 	master->bus_num = -1;
@@ -1164,7 +1159,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_put(&pdev->dev);
 
 
 	master->dev.of_node = pdev->dev.of_node;
 	master->dev.of_node = pdev->dev.of_node;
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		dev_err(&pdev->dev, "can not register to master err %d\n", ret);
 		goto exit_pm_disable;
 		goto exit_pm_disable;
@@ -1191,7 +1186,6 @@ static int tegra_slink_remove(struct platform_device *pdev)
 	struct tegra_slink_data	*tspi = spi_master_get_devdata(master);
 	struct tegra_slink_data	*tspi = spi_master_get_devdata(master);
 
 
 	free_irq(tspi->irq, tspi);
 	free_irq(tspi->irq, tspi);
-	spi_unregister_master(master);
 
 
 	if (tspi->tx_dma_chan)
 	if (tspi->tx_dma_chan)
 		tegra_slink_deinit_dma_param(tspi, false);
 		tegra_slink_deinit_dma_param(tspi, false);

+ 9 - 37
drivers/spi/spi-ti-qspi.c

@@ -41,9 +41,6 @@ struct ti_qspi_regs {
 struct ti_qspi {
 struct ti_qspi {
 	struct completion       transfer_complete;
 	struct completion       transfer_complete;
 
 
-	/* IRQ synchronization */
-	spinlock_t              lock;
-
 	/* list synchronization */
 	/* list synchronization */
 	struct mutex            list_lock;
 	struct mutex            list_lock;
 
 
@@ -57,7 +54,6 @@ struct ti_qspi {
 	u32 spi_max_frequency;
 	u32 spi_max_frequency;
 	u32 cmd;
 	u32 cmd;
 	u32 dc;
 	u32 dc;
-	u32 stat;
 };
 };
 
 
 #define QSPI_PID			(0x0)
 #define QSPI_PID			(0x0)
@@ -397,13 +393,12 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id)
 {
 {
 	struct ti_qspi *qspi = dev_id;
 	struct ti_qspi *qspi = dev_id;
 	u16 int_stat;
 	u16 int_stat;
+	u32 stat;
 
 
 	irqreturn_t ret = IRQ_HANDLED;
 	irqreturn_t ret = IRQ_HANDLED;
 
 
-	spin_lock(&qspi->lock);
-
 	int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR);
 	int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR);
-	qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
+	stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG);
 
 
 	if (!int_stat) {
 	if (!int_stat) {
 		dev_dbg(qspi->dev, "No IRQ triggered\n");
 		dev_dbg(qspi->dev, "No IRQ triggered\n");
@@ -411,35 +406,14 @@ static irqreturn_t ti_qspi_isr(int irq, void *dev_id)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	ret = IRQ_WAKE_THREAD;
-
-	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
 	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE,
 	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE,
 				QSPI_INTR_STATUS_ENABLED_CLEAR);
 				QSPI_INTR_STATUS_ENABLED_CLEAR);
-
+	if (stat & WC)
+		complete(&qspi->transfer_complete);
 out:
 out:
-	spin_unlock(&qspi->lock);
-
 	return ret;
 	return ret;
 }
 }
 
 
-static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id)
-{
-	struct ti_qspi *qspi = dev_id;
-	unsigned long flags;
-
-	spin_lock_irqsave(&qspi->lock, flags);
-
-	if (qspi->stat & WC)
-		complete(&qspi->transfer_complete);
-
-	spin_unlock_irqrestore(&qspi->lock, flags);
-
-	ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);
-
-	return IRQ_HANDLED;
-}
-
 static int ti_qspi_runtime_resume(struct device *dev)
 static int ti_qspi_runtime_resume(struct device *dev)
 {
 {
 	struct ti_qspi      *qspi;
 	struct ti_qspi      *qspi;
@@ -472,7 +446,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
 	if (!master)
 	if (!master)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	master->mode_bits = SPI_CPOL | SPI_CPHA;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
 
 
 	master->bus_num = -1;
 	master->bus_num = -1;
 	master->flags = SPI_MASTER_HALF_DUPLEX;
 	master->flags = SPI_MASTER_HALF_DUPLEX;
@@ -499,7 +473,6 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		return irq;
 		return irq;
 	}
 	}
 
 
-	spin_lock_init(&qspi->lock);
 	mutex_init(&qspi->list_lock);
 	mutex_init(&qspi->list_lock);
 
 
 	qspi->base = devm_ioremap_resource(&pdev->dev, r);
 	qspi->base = devm_ioremap_resource(&pdev->dev, r);
@@ -508,8 +481,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		goto free_master;
 		goto free_master;
 	}
 	}
 
 
-	ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr,
-			ti_qspi_threaded_isr, 0,
+	ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,
 			dev_name(&pdev->dev), qspi);
 			dev_name(&pdev->dev), qspi);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
 		dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
@@ -532,7 +504,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
 	if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))
 	if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))
 		qspi->spi_max_frequency = max_freq;
 		qspi->spi_max_frequency = max_freq;
 
 
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret)
 	if (ret)
 		goto free_master;
 		goto free_master;
 
 
@@ -547,7 +519,7 @@ static int ti_qspi_remove(struct platform_device *pdev)
 {
 {
 	struct	ti_qspi *qspi = platform_get_drvdata(pdev);
 	struct	ti_qspi *qspi = platform_get_drvdata(pdev);
 
 
-	spi_unregister_master(qspi->master);
+	ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -558,7 +530,7 @@ static const struct dev_pm_ops ti_qspi_pm_ops = {
 
 
 static struct platform_driver ti_qspi_driver = {
 static struct platform_driver ti_qspi_driver = {
 	.probe	= ti_qspi_probe,
 	.probe	= ti_qspi_probe,
-	.remove	= ti_qspi_remove,
+	.remove = ti_qspi_remove,
 	.driver = {
 	.driver = {
 		.name	= "ti,dra7xxx-qspi",
 		.name	= "ti,dra7xxx-qspi",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,

+ 9 - 8
drivers/spi/spi-topcliff-pch.c

@@ -506,8 +506,8 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)
 		goto err_out;
 		goto err_out;
 	}
 	}
 
 
-	dev_dbg(&pspi->dev, "%s Transfer List not empty. "
-		"Transfer Speed is set.\n", __func__);
+	dev_dbg(&pspi->dev,
+		"%s Transfer List not empty. Transfer Speed is set.\n", __func__);
 
 
 	spin_lock_irqsave(&data->lock, flags);
 	spin_lock_irqsave(&data->lock, flags);
 	/* validate Tx/Rx buffers and Transfer length */
 	/* validate Tx/Rx buffers and Transfer length */
@@ -526,8 +526,9 @@ static int pch_spi_transfer(struct spi_device *pspi, struct spi_message *pmsg)
 			goto err_return_spinlock;
 			goto err_return_spinlock;
 		}
 		}
 
 
-		dev_dbg(&pspi->dev, "%s Tx/Rx buffer valid. Transfer length"
-			" valid\n", __func__);
+		dev_dbg(&pspi->dev,
+			"%s Tx/Rx buffer valid. Transfer length valid\n",
+			__func__);
 
 
 		/* if baud rate has been specified validate the same */
 		/* if baud rate has been specified validate the same */
 		if (transfer->speed_hz > PCH_MAX_BAUDRATE)
 		if (transfer->speed_hz > PCH_MAX_BAUDRATE)
@@ -1181,8 +1182,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)
 	spin_lock(&data->lock);
 	spin_lock(&data->lock);
 	/* check if suspend has been initiated;if yes flush queue */
 	/* check if suspend has been initiated;if yes flush queue */
 	if (data->board_dat->suspend_sts || (data->status == STATUS_EXITING)) {
 	if (data->board_dat->suspend_sts || (data->status == STATUS_EXITING)) {
-		dev_dbg(&data->master->dev, "%s suspend/remove initiated,"
-			"flushing queue\n", __func__);
+		dev_dbg(&data->master->dev,
+			"%s suspend/remove initiated, flushing queue\n", __func__);
 		list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {
 		list_for_each_entry_safe(pmsg, tmp, data->queue.next, queue) {
 			pmsg->status = -EIO;
 			pmsg->status = -EIO;
 
 
@@ -1410,13 +1411,13 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
 	/* baseaddress + address offset) */
 	/* baseaddress + address offset) */
 	data->io_base_addr = pci_resource_start(board_dat->pdev, 1) +
 	data->io_base_addr = pci_resource_start(board_dat->pdev, 1) +
 					 PCH_ADDRESS_SIZE * plat_dev->id;
 					 PCH_ADDRESS_SIZE * plat_dev->id;
-	data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0) +
-					 PCH_ADDRESS_SIZE * plat_dev->id;
+	data->io_remap_addr = pci_iomap(board_dat->pdev, 1, 0);
 	if (!data->io_remap_addr) {
 	if (!data->io_remap_addr) {
 		dev_err(&plat_dev->dev, "%s pci_iomap failed\n", __func__);
 		dev_err(&plat_dev->dev, "%s pci_iomap failed\n", __func__);
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto err_pci_iomap;
 		goto err_pci_iomap;
 	}
 	}
+	data->io_remap_addr += PCH_ADDRESS_SIZE * plat_dev->id;
 
 
 	dev_dbg(&plat_dev->dev, "[ch%d] remap_addr=%p\n",
 	dev_dbg(&plat_dev->dev, "[ch%d] remap_addr=%p\n",
 		plat_dev->id, data->io_remap_addr);
 		plat_dev->id, data->io_remap_addr);

+ 5 - 6
drivers/spi/spi-txx9.c

@@ -177,7 +177,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)
 			| 0x08,
 			| 0x08,
 			TXx9_SPCR0);
 			TXx9_SPCR0);
 
 
-	list_for_each_entry (t, &m->transfers, transfer_list) {
+	list_for_each_entry(t, &m->transfers, transfer_list) {
 		const void *txbuf = t->tx_buf;
 		const void *txbuf = t->tx_buf;
 		void *rxbuf = t->rx_buf;
 		void *rxbuf = t->rx_buf;
 		u32 data;
 		u32 data;
@@ -308,7 +308,7 @@ static int txx9spi_transfer(struct spi_device *spi, struct spi_message *m)
 	m->actual_length = 0;
 	m->actual_length = 0;
 
 
 	/* check each transfer's parameters */
 	/* check each transfer's parameters */
-	list_for_each_entry (t, &m->transfers, transfer_list) {
+	list_for_each_entry(t, &m->transfers, transfer_list) {
 		u32 speed_hz = t->speed_hz ? : spi->max_speed_hz;
 		u32 speed_hz = t->speed_hz ? : spi->max_speed_hz;
 		u8 bits_per_word = t->bits_per_word;
 		u8 bits_per_word = t->bits_per_word;
 
 
@@ -406,7 +406,7 @@ static int txx9spi_probe(struct platform_device *dev)
 	master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */
 	master->num_chipselect = (u16)UINT_MAX; /* any GPIO numbers */
 	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 	master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
 
 
-	ret = spi_register_master(master);
+	ret = devm_spi_register_master(&dev->dev, master);
 	if (ret)
 	if (ret)
 		goto exit;
 		goto exit;
 	return 0;
 	return 0;
@@ -428,11 +428,9 @@ static int txx9spi_remove(struct platform_device *dev)
 	struct spi_master *master = spi_master_get(platform_get_drvdata(dev));
 	struct spi_master *master = spi_master_get(platform_get_drvdata(dev));
 	struct txx9spi *c = spi_master_get_devdata(master);
 	struct txx9spi *c = spi_master_get_devdata(master);
 
 
-	spi_unregister_master(master);
 	destroy_workqueue(c->workqueue);
 	destroy_workqueue(c->workqueue);
 	clk_disable(c->clk);
 	clk_disable(c->clk);
 	clk_put(c->clk);
 	clk_put(c->clk);
-	spi_master_put(master);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -440,6 +438,7 @@ static int txx9spi_remove(struct platform_device *dev)
 MODULE_ALIAS("platform:spi_txx9");
 MODULE_ALIAS("platform:spi_txx9");
 
 
 static struct platform_driver txx9spi_driver = {
 static struct platform_driver txx9spi_driver = {
+	.probe = txx9spi_probe,
 	.remove = txx9spi_remove,
 	.remove = txx9spi_remove,
 	.driver = {
 	.driver = {
 		.name = "spi_txx9",
 		.name = "spi_txx9",
@@ -449,7 +448,7 @@ static struct platform_driver txx9spi_driver = {
 
 
 static int __init txx9spi_init(void)
 static int __init txx9spi_init(void)
 {
 {
-	return platform_driver_probe(&txx9spi_driver, txx9spi_probe);
+	return platform_driver_register(&txx9spi_driver);
 }
 }
 subsys_initcall(txx9spi_init);
 subsys_initcall(txx9spi_init);
 
 

+ 1 - 1
drivers/spi/spi-xilinx.c

@@ -372,7 +372,7 @@ static int xilinx_spi_probe(struct platform_device *pdev)
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 	master->mode_bits = SPI_CPOL | SPI_CPHA;
 
 
 	xspi = spi_master_get_devdata(master);
 	xspi = spi_master_get_devdata(master);
-	xspi->bitbang.master = spi_master_get(master);
+	xspi->bitbang.master = master;
 	xspi->bitbang.chipselect = xilinx_spi_chipselect;
 	xspi->bitbang.chipselect = xilinx_spi_chipselect;
 	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
 	xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
 	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
 	xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;

+ 201 - 43
drivers/spi/spi.c

@@ -39,6 +39,9 @@
 #include <linux/ioport.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
 
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/spi.h>
+
 static void spidev_release(struct device *dev)
 static void spidev_release(struct device *dev)
 {
 {
 	struct spi_device	*spi = to_spi_device(dev);
 	struct spi_device	*spi = to_spi_device(dev);
@@ -58,11 +61,13 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf)
 
 
 	return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias);
 	return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias);
 }
 }
+static DEVICE_ATTR_RO(modalias);
 
 
-static struct device_attribute spi_dev_attrs[] = {
-	__ATTR_RO(modalias),
-	__ATTR_NULL,
+static struct attribute *spi_dev_attrs[] = {
+	&dev_attr_modalias.attr,
+	NULL,
 };
 };
+ATTRIBUTE_GROUPS(spi_dev);
 
 
 /* modalias support makes "modprobe $MODALIAS" new-style hotplug work,
 /* modalias support makes "modprobe $MODALIAS" new-style hotplug work,
  * and the sysfs version makes coldplug work too.
  * and the sysfs version makes coldplug work too.
@@ -229,7 +234,7 @@ static const struct dev_pm_ops spi_pm = {
 
 
 struct bus_type spi_bus_type = {
 struct bus_type spi_bus_type = {
 	.name		= "spi",
 	.name		= "spi",
-	.dev_attrs	= spi_dev_attrs,
+	.dev_groups	= spi_dev_groups,
 	.match		= spi_match_device,
 	.match		= spi_match_device,
 	.uevent		= spi_uevent,
 	.uevent		= spi_uevent,
 	.pm		= &spi_pm,
 	.pm		= &spi_pm,
@@ -323,7 +328,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master)
 	if (!spi_master_get(master))
 	if (!spi_master_get(master))
 		return NULL;
 		return NULL;
 
 
-	spi = kzalloc(sizeof *spi, GFP_KERNEL);
+	spi = kzalloc(sizeof(*spi), GFP_KERNEL);
 	if (!spi) {
 	if (!spi) {
 		dev_err(dev, "cannot alloc spi_device\n");
 		dev_err(dev, "cannot alloc spi_device\n");
 		spi_master_put(master);
 		spi_master_put(master);
@@ -523,6 +528,95 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n)
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
+static void spi_set_cs(struct spi_device *spi, bool enable)
+{
+	if (spi->mode & SPI_CS_HIGH)
+		enable = !enable;
+
+	if (spi->cs_gpio >= 0)
+		gpio_set_value(spi->cs_gpio, !enable);
+	else if (spi->master->set_cs)
+		spi->master->set_cs(spi, !enable);
+}
+
+/*
+ * spi_transfer_one_message - Default implementation of transfer_one_message()
+ *
+ * This is a standard implementation of transfer_one_message() for
+ * drivers which impelment a transfer_one() operation.  It provides
+ * standard handling of delays and chip select management.
+ */
+static int spi_transfer_one_message(struct spi_master *master,
+				    struct spi_message *msg)
+{
+	struct spi_transfer *xfer;
+	bool cur_cs = true;
+	bool keep_cs = false;
+	int ret = 0;
+
+	spi_set_cs(msg->spi, true);
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		trace_spi_transfer_start(msg, xfer);
+
+		INIT_COMPLETION(master->xfer_completion);
+
+		ret = master->transfer_one(master, msg->spi, xfer);
+		if (ret < 0) {
+			dev_err(&msg->spi->dev,
+				"SPI transfer failed: %d\n", ret);
+			goto out;
+		}
+
+		if (ret > 0)
+			wait_for_completion(&master->xfer_completion);
+
+		trace_spi_transfer_stop(msg, xfer);
+
+		if (msg->status != -EINPROGRESS)
+			goto out;
+
+		if (xfer->delay_usecs)
+			udelay(xfer->delay_usecs);
+
+		if (xfer->cs_change) {
+			if (list_is_last(&xfer->transfer_list,
+					 &msg->transfers)) {
+				keep_cs = true;
+			} else {
+				cur_cs = !cur_cs;
+				spi_set_cs(msg->spi, cur_cs);
+			}
+		}
+
+		msg->actual_length += xfer->len;
+	}
+
+out:
+	if (ret != 0 || !keep_cs)
+		spi_set_cs(msg->spi, false);
+
+	if (msg->status == -EINPROGRESS)
+		msg->status = ret;
+
+	spi_finalize_current_message(master);
+
+	return ret;
+}
+
+/**
+ * spi_finalize_current_transfer - report completion of a transfer
+ *
+ * Called by SPI drivers using the core transfer_one_message()
+ * implementation to notify it that the current interrupt driven
+ * transfer has finised and the next one may be scheduled.
+ */
+void spi_finalize_current_transfer(struct spi_master *master)
+{
+	complete(&master->xfer_completion);
+}
+EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
+
 /**
 /**
  * spi_pump_messages - kthread work function which processes spi message queue
  * spi_pump_messages - kthread work function which processes spi message queue
  * @work: pointer to kthread work struct contained in the master struct
  * @work: pointer to kthread work struct contained in the master struct
@@ -557,6 +651,7 @@ static void spi_pump_messages(struct kthread_work *work)
 			pm_runtime_mark_last_busy(master->dev.parent);
 			pm_runtime_mark_last_busy(master->dev.parent);
 			pm_runtime_put_autosuspend(master->dev.parent);
 			pm_runtime_put_autosuspend(master->dev.parent);
 		}
 		}
+		trace_spi_master_idle(master);
 		return;
 		return;
 	}
 	}
 
 
@@ -585,6 +680,9 @@ static void spi_pump_messages(struct kthread_work *work)
 		}
 		}
 	}
 	}
 
 
+	if (!was_busy)
+		trace_spi_master_busy(master);
+
 	if (!was_busy && master->prepare_transfer_hardware) {
 	if (!was_busy && master->prepare_transfer_hardware) {
 		ret = master->prepare_transfer_hardware(master);
 		ret = master->prepare_transfer_hardware(master);
 		if (ret) {
 		if (ret) {
@@ -597,6 +695,20 @@ static void spi_pump_messages(struct kthread_work *work)
 		}
 		}
 	}
 	}
 
 
+	trace_spi_message_start(master->cur_msg);
+
+	if (master->prepare_message) {
+		ret = master->prepare_message(master, master->cur_msg);
+		if (ret) {
+			dev_err(&master->dev,
+				"failed to prepare message: %d\n", ret);
+			master->cur_msg->status = ret;
+			spi_finalize_current_message(master);
+			return;
+		}
+		master->cur_msg_prepared = true;
+	}
+
 	ret = master->transfer_one_message(master, master->cur_msg);
 	ret = master->transfer_one_message(master, master->cur_msg);
 	if (ret) {
 	if (ret) {
 		dev_err(&master->dev,
 		dev_err(&master->dev,
@@ -678,6 +790,7 @@ void spi_finalize_current_message(struct spi_master *master)
 {
 {
 	struct spi_message *mesg;
 	struct spi_message *mesg;
 	unsigned long flags;
 	unsigned long flags;
+	int ret;
 
 
 	spin_lock_irqsave(&master->queue_lock, flags);
 	spin_lock_irqsave(&master->queue_lock, flags);
 	mesg = master->cur_msg;
 	mesg = master->cur_msg;
@@ -686,9 +799,20 @@ void spi_finalize_current_message(struct spi_master *master)
 	queue_kthread_work(&master->kworker, &master->pump_messages);
 	queue_kthread_work(&master->kworker, &master->pump_messages);
 	spin_unlock_irqrestore(&master->queue_lock, flags);
 	spin_unlock_irqrestore(&master->queue_lock, flags);
 
 
+	if (master->cur_msg_prepared && master->unprepare_message) {
+		ret = master->unprepare_message(master, mesg);
+		if (ret) {
+			dev_err(&master->dev,
+				"failed to unprepare message: %d\n", ret);
+		}
+	}
+	master->cur_msg_prepared = false;
+
 	mesg->state = NULL;
 	mesg->state = NULL;
 	if (mesg->complete)
 	if (mesg->complete)
 		mesg->complete(mesg->context);
 		mesg->complete(mesg->context);
+
+	trace_spi_message_done(mesg);
 }
 }
 EXPORT_SYMBOL_GPL(spi_finalize_current_message);
 EXPORT_SYMBOL_GPL(spi_finalize_current_message);
 
 
@@ -803,6 +927,8 @@ static int spi_master_initialize_queue(struct spi_master *master)
 
 
 	master->queued = true;
 	master->queued = true;
 	master->transfer = spi_queued_transfer;
 	master->transfer = spi_queued_transfer;
+	if (!master->transfer_one_message)
+		master->transfer_one_message = spi_transfer_one_message;
 
 
 	/* Initialize and start queue */
 	/* Initialize and start queue */
 	ret = spi_init_queue(master);
 	ret = spi_init_queue(master);
@@ -838,10 +964,8 @@ static void of_register_spi_devices(struct spi_master *master)
 {
 {
 	struct spi_device *spi;
 	struct spi_device *spi;
 	struct device_node *nc;
 	struct device_node *nc;
-	const __be32 *prop;
-	char modalias[SPI_NAME_SIZE + 4];
 	int rc;
 	int rc;
-	int len;
+	u32 value;
 
 
 	if (!master->dev.of_node)
 	if (!master->dev.of_node)
 		return;
 		return;
@@ -866,14 +990,14 @@ static void of_register_spi_devices(struct spi_master *master)
 		}
 		}
 
 
 		/* Device address */
 		/* Device address */
-		prop = of_get_property(nc, "reg", &len);
-		if (!prop || len < sizeof(*prop)) {
-			dev_err(&master->dev, "%s has no 'reg' property\n",
-				nc->full_name);
+		rc = of_property_read_u32(nc, "reg", &value);
+		if (rc) {
+			dev_err(&master->dev, "%s has no valid 'reg' property (%d)\n",
+				nc->full_name, rc);
 			spi_dev_put(spi);
 			spi_dev_put(spi);
 			continue;
 			continue;
 		}
 		}
-		spi->chip_select = be32_to_cpup(prop);
+		spi->chip_select = value;
 
 
 		/* Mode (clock phase/polarity/etc.) */
 		/* Mode (clock phase/polarity/etc.) */
 		if (of_find_property(nc, "spi-cpha", NULL))
 		if (of_find_property(nc, "spi-cpha", NULL))
@@ -886,55 +1010,53 @@ static void of_register_spi_devices(struct spi_master *master)
 			spi->mode |= SPI_3WIRE;
 			spi->mode |= SPI_3WIRE;
 
 
 		/* Device DUAL/QUAD mode */
 		/* Device DUAL/QUAD mode */
-		prop = of_get_property(nc, "spi-tx-bus-width", &len);
-		if (prop && len == sizeof(*prop)) {
-			switch (be32_to_cpup(prop)) {
-			case SPI_NBITS_SINGLE:
+		if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
+			switch (value) {
+			case 1:
 				break;
 				break;
-			case SPI_NBITS_DUAL:
+			case 2:
 				spi->mode |= SPI_TX_DUAL;
 				spi->mode |= SPI_TX_DUAL;
 				break;
 				break;
-			case SPI_NBITS_QUAD:
+			case 4:
 				spi->mode |= SPI_TX_QUAD;
 				spi->mode |= SPI_TX_QUAD;
 				break;
 				break;
 			default:
 			default:
 				dev_err(&master->dev,
 				dev_err(&master->dev,
 					"spi-tx-bus-width %d not supported\n",
 					"spi-tx-bus-width %d not supported\n",
-					be32_to_cpup(prop));
+					value);
 				spi_dev_put(spi);
 				spi_dev_put(spi);
 				continue;
 				continue;
 			}
 			}
 		}
 		}
 
 
-		prop = of_get_property(nc, "spi-rx-bus-width", &len);
-		if (prop && len == sizeof(*prop)) {
-			switch (be32_to_cpup(prop)) {
-			case SPI_NBITS_SINGLE:
+		if (!of_property_read_u32(nc, "spi-rx-bus-width", &value)) {
+			switch (value) {
+			case 1:
 				break;
 				break;
-			case SPI_NBITS_DUAL:
+			case 2:
 				spi->mode |= SPI_RX_DUAL;
 				spi->mode |= SPI_RX_DUAL;
 				break;
 				break;
-			case SPI_NBITS_QUAD:
+			case 4:
 				spi->mode |= SPI_RX_QUAD;
 				spi->mode |= SPI_RX_QUAD;
 				break;
 				break;
 			default:
 			default:
 				dev_err(&master->dev,
 				dev_err(&master->dev,
 					"spi-rx-bus-width %d not supported\n",
 					"spi-rx-bus-width %d not supported\n",
-					be32_to_cpup(prop));
+					value);
 				spi_dev_put(spi);
 				spi_dev_put(spi);
 				continue;
 				continue;
 			}
 			}
 		}
 		}
 
 
 		/* Device speed */
 		/* Device speed */
-		prop = of_get_property(nc, "spi-max-frequency", &len);
-		if (!prop || len < sizeof(*prop)) {
-			dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n",
-				nc->full_name);
+		rc = of_property_read_u32(nc, "spi-max-frequency", &value);
+		if (rc) {
+			dev_err(&master->dev, "%s has no valid 'spi-max-frequency' property (%d)\n",
+				nc->full_name, rc);
 			spi_dev_put(spi);
 			spi_dev_put(spi);
 			continue;
 			continue;
 		}
 		}
-		spi->max_speed_hz = be32_to_cpup(prop);
+		spi->max_speed_hz = value;
 
 
 		/* IRQ */
 		/* IRQ */
 		spi->irq = irq_of_parse_and_map(nc, 0);
 		spi->irq = irq_of_parse_and_map(nc, 0);
@@ -944,9 +1066,7 @@ static void of_register_spi_devices(struct spi_master *master)
 		spi->dev.of_node = nc;
 		spi->dev.of_node = nc;
 
 
 		/* Register the new device */
 		/* Register the new device */
-		snprintf(modalias, sizeof(modalias), "%s%s", SPI_MODULE_PREFIX,
-			 spi->modalias);
-		request_module(modalias);
+		request_module("%s%s", SPI_MODULE_PREFIX, spi->modalias);
 		rc = spi_add_device(spi);
 		rc = spi_add_device(spi);
 		if (rc) {
 		if (rc) {
 			dev_err(&master->dev, "spi_device register error %s\n",
 			dev_err(&master->dev, "spi_device register error %s\n",
@@ -1025,7 +1145,7 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
 		return AE_OK;
 		return AE_OK;
 	}
 	}
 
 
-	strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
+	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
 	if (spi_add_device(spi)) {
 	if (spi_add_device(spi)) {
 		dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
 		dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
 			dev_name(&adev->dev));
 			dev_name(&adev->dev));
@@ -1097,7 +1217,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
 	if (!dev)
 	if (!dev)
 		return NULL;
 		return NULL;
 
 
-	master = kzalloc(size + sizeof *master, GFP_KERNEL);
+	master = kzalloc(size + sizeof(*master), GFP_KERNEL);
 	if (!master)
 	if (!master)
 		return NULL;
 		return NULL;
 
 
@@ -1122,7 +1242,7 @@ static int of_spi_register_master(struct spi_master *master)
 		return 0;
 		return 0;
 
 
 	nb = of_gpio_named_count(np, "cs-gpios");
 	nb = of_gpio_named_count(np, "cs-gpios");
-	master->num_chipselect = max(nb, (int)master->num_chipselect);
+	master->num_chipselect = max_t(int, nb, master->num_chipselect);
 
 
 	/* Return error only for an incorrectly formed cs-gpios property */
 	/* Return error only for an incorrectly formed cs-gpios property */
 	if (nb == 0 || nb == -ENOENT)
 	if (nb == 0 || nb == -ENOENT)
@@ -1209,6 +1329,7 @@ int spi_register_master(struct spi_master *master)
 	spin_lock_init(&master->bus_lock_spinlock);
 	spin_lock_init(&master->bus_lock_spinlock);
 	mutex_init(&master->bus_lock_mutex);
 	mutex_init(&master->bus_lock_mutex);
 	master->bus_lock_flag = 0;
 	master->bus_lock_flag = 0;
+	init_completion(&master->xfer_completion);
 
 
 	/* register the device, then userspace will see it.
 	/* register the device, then userspace will see it.
 	 * registration fails if the bus ID is in use.
 	 * registration fails if the bus ID is in use.
@@ -1245,6 +1366,41 @@ done:
 }
 }
 EXPORT_SYMBOL_GPL(spi_register_master);
 EXPORT_SYMBOL_GPL(spi_register_master);
 
 
+static void devm_spi_unregister(struct device *dev, void *res)
+{
+	spi_unregister_master(*(struct spi_master **)res);
+}
+
+/**
+ * dev_spi_register_master - register managed SPI master controller
+ * @dev:    device managing SPI master
+ * @master: initialized master, originally from spi_alloc_master()
+ * Context: can sleep
+ *
+ * Register a SPI device as with spi_register_master() which will
+ * automatically be unregister
+ */
+int devm_spi_register_master(struct device *dev, struct spi_master *master)
+{
+	struct spi_master **ptr;
+	int ret;
+
+	ptr = devres_alloc(devm_spi_unregister, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	ret = spi_register_master(master);
+	if (ret != 0) {
+		*ptr = master;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_spi_register_master);
+
 static int __unregister(struct device *dev, void *null)
 static int __unregister(struct device *dev, void *null)
 {
 {
 	spi_unregister_device(to_spi_device(dev));
 	spi_unregister_device(to_spi_device(dev));
@@ -1402,8 +1558,7 @@ int spi_setup(struct spi_device *spi)
 	if (spi->master->setup)
 	if (spi->master->setup)
 		status = spi->master->setup(spi);
 		status = spi->master->setup(spi);
 
 
-	dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s"
-				"%u bits/w, %u Hz max --> %d\n",
+	dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",
 			(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
 			(int) (spi->mode & (SPI_CPOL | SPI_CPHA)),
 			(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
 			(spi->mode & SPI_CS_HIGH) ? "cs_high, " : "",
 			(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
 			(spi->mode & SPI_LSB_FIRST) ? "lsb, " : "",
@@ -1421,6 +1576,10 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
 	struct spi_master *master = spi->master;
 	struct spi_master *master = spi->master;
 	struct spi_transfer *xfer;
 	struct spi_transfer *xfer;
 
 
+	message->spi = spi;
+
+	trace_spi_message_submit(message);
+
 	if (list_empty(&message->transfers))
 	if (list_empty(&message->transfers))
 		return -EINVAL;
 		return -EINVAL;
 	if (!message->complete)
 	if (!message->complete)
@@ -1520,7 +1679,6 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message)
 		}
 		}
 	}
 	}
 
 
-	message->spi = spi;
 	message->status = -EINPROGRESS;
 	message->status = -EINPROGRESS;
 	return master->transfer(spi, message);
 	return master->transfer(spi, message);
 }
 }
@@ -1762,7 +1920,7 @@ int spi_bus_unlock(struct spi_master *master)
 EXPORT_SYMBOL_GPL(spi_bus_unlock);
 EXPORT_SYMBOL_GPL(spi_bus_unlock);
 
 
 /* portable code must never pass more than 32 bytes */
 /* portable code must never pass more than 32 bytes */
-#define	SPI_BUFSIZ	max(32,SMP_CACHE_BYTES)
+#define	SPI_BUFSIZ	max(32, SMP_CACHE_BYTES)
 
 
 static u8	*buf;
 static u8	*buf;
 
 
@@ -1811,7 +1969,7 @@ int spi_write_then_read(struct spi_device *spi,
 	}
 	}
 
 
 	spi_message_init(&message);
 	spi_message_init(&message);
-	memset(x, 0, sizeof x);
+	memset(x, 0, sizeof(x));
 	if (n_tx) {
 	if (n_tx) {
 		x[0].len = n_tx;
 		x[0].len = n_tx;
 		spi_message_add_tail(&x[0], &message);
 		spi_message_add_tail(&x[0], &message);

+ 3 - 4
drivers/spi/spidev.c

@@ -37,7 +37,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spidev.h>
 #include <linux/spi/spidev.h>
 
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 
 
 
 /*
 /*
@@ -206,9 +206,9 @@ spidev_write(struct file *filp, const char __user *buf,
 
 
 	mutex_lock(&spidev->buf_lock);
 	mutex_lock(&spidev->buf_lock);
 	missing = copy_from_user(spidev->buffer, buf, count);
 	missing = copy_from_user(spidev->buffer, buf, count);
-	if (missing == 0) {
+	if (missing == 0)
 		status = spidev_sync_write(spidev, count);
 		status = spidev_sync_write(spidev, count);
-	} else
+	else
 		status = -EFAULT;
 		status = -EFAULT;
 	mutex_unlock(&spidev->buf_lock);
 	mutex_unlock(&spidev->buf_lock);
 
 
@@ -629,7 +629,6 @@ static int spidev_remove(struct spi_device *spi)
 	/* make sure ops on existing fds can abort cleanly */
 	/* make sure ops on existing fds can abort cleanly */
 	spin_lock_irq(&spidev->spi_lock);
 	spin_lock_irq(&spidev->spi_lock);
 	spidev->spi = NULL;
 	spidev->spi = NULL;
-	spi_set_drvdata(spi, NULL);
 	spin_unlock_irq(&spidev->spi_lock);
 	spin_unlock_irq(&spidev->spi_lock);
 
 
 	/* prevent new opens */
 	/* prevent new opens */

+ 1 - 2
drivers/staging/iio/meter/ade7753.c

@@ -86,7 +86,7 @@ static int ade7753_spi_read_reg_16(struct device *dev,
 	struct ade7753_state *st = iio_priv(indio_dev);
 	struct ade7753_state *st = iio_priv(indio_dev);
 	ssize_t ret;
 	ssize_t ret;
 
 
-	ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address));
+	ret = spi_w8r16be(st->us, ADE7753_READ_REG(reg_address));
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 			reg_address);
 			reg_address);
@@ -94,7 +94,6 @@ static int ade7753_spi_read_reg_16(struct device *dev,
 	}
 	}
 
 
 	*val = ret;
 	*val = ret;
-	*val = be16_to_cpup(val);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 2
drivers/staging/iio/meter/ade7754.c

@@ -86,7 +86,7 @@ static int ade7754_spi_read_reg_16(struct device *dev,
 	struct ade7754_state *st = iio_priv(indio_dev);
 	struct ade7754_state *st = iio_priv(indio_dev);
 	int ret;
 	int ret;
 
 
-	ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address));
+	ret = spi_w8r16be(st->us, ADE7754_READ_REG(reg_address));
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 			reg_address);
 			reg_address);
@@ -94,7 +94,6 @@ static int ade7754_spi_read_reg_16(struct device *dev,
 	}
 	}
 
 
 	*val = ret;
 	*val = ret;
-	*val = be16_to_cpup(val);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 2
drivers/staging/iio/meter/ade7759.c

@@ -86,7 +86,7 @@ static int ade7759_spi_read_reg_16(struct device *dev,
 	struct ade7759_state *st = iio_priv(indio_dev);
 	struct ade7759_state *st = iio_priv(indio_dev);
 	int ret;
 	int ret;
 
 
-	ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address));
+	ret = spi_w8r16be(st->us, ADE7759_READ_REG(reg_address));
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 			reg_address);
 			reg_address);
@@ -94,7 +94,6 @@ static int ade7759_spi_read_reg_16(struct device *dev,
 	}
 	}
 
 
 	*val = ret;
 	*val = ret;
-	*val = be16_to_cpup(val);
 
 
 	return 0;
 	return 0;
 }
 }

+ 2 - 0
include/linux/spi/rspi.h

@@ -26,6 +26,8 @@ struct rspi_plat_data {
 	unsigned int dma_rx_id;
 	unsigned int dma_rx_id;
 
 
 	unsigned dma_width_16bit:1;	/* DMAC read/write width = 16-bit */
 	unsigned dma_width_16bit:1;	/* DMAC read/write width = 16-bit */
+
+	u16 num_chipselect;
 };
 };
 
 
 #endif
 #endif

+ 59 - 2
include/linux/spi/spi.h

@@ -23,6 +23,7 @@
 #include <linux/mod_devicetable.h>
 #include <linux/mod_devicetable.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
 #include <linux/kthread.h>
+#include <linux/completion.h>
 
 
 /*
 /*
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
  * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -150,8 +151,7 @@ static inline void *spi_get_drvdata(struct spi_device *spi)
 }
 }
 
 
 struct spi_message;
 struct spi_message;
-
-
+struct spi_transfer;
 
 
 /**
 /**
  * struct spi_driver - Host side "protocol" driver
  * struct spi_driver - Host side "protocol" driver
@@ -257,6 +257,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @queue_lock: spinlock to syncronise access to message queue
  * @queue_lock: spinlock to syncronise access to message queue
  * @queue: message queue
  * @queue: message queue
  * @cur_msg: the currently in-flight message
  * @cur_msg: the currently in-flight message
+ * @cur_msg_prepared: spi_prepare_message was called for the currently
+ *                    in-flight message
+ * @xfer_completion: used by core tranfer_one_message()
  * @busy: message pump is busy
  * @busy: message pump is busy
  * @running: message pump is running
  * @running: message pump is running
  * @rt: whether this queue is set to run as a realtime task
  * @rt: whether this queue is set to run as a realtime task
@@ -274,6 +277,16 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @unprepare_transfer_hardware: there are currently no more messages on the
  * @unprepare_transfer_hardware: there are currently no more messages on the
  *	queue so the subsystem notifies the driver that it may relax the
  *	queue so the subsystem notifies the driver that it may relax the
  *	hardware by issuing this call
  *	hardware by issuing this call
+ * @set_cs: assert or deassert chip select, true to assert.  May be called
+ *          from interrupt context.
+ * @prepare_message: set up the controller to transfer a single message,
+ *                   for example doing DMA mapping.  Called from threaded
+ *                   context.
+ * @transfer_one: transfer a single spi_transfer. When the
+ *	          driver is finished with this transfer it must call
+ *	          spi_finalize_current_transfer() so the subsystem can issue
+ *                the next transfer
+ * @unprepare_message: undo any work done by prepare_message().
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *	number. Any individual value may be -ENOENT for CS lines that
  *	number. Any individual value may be -ENOENT for CS lines that
  *	are not GPIOs (driven by the SPI controller itself).
  *	are not GPIOs (driven by the SPI controller itself).
@@ -388,11 +401,25 @@ struct spi_master {
 	bool				running;
 	bool				running;
 	bool				rt;
 	bool				rt;
 	bool				auto_runtime_pm;
 	bool				auto_runtime_pm;
+	bool                            cur_msg_prepared;
+	struct completion               xfer_completion;
 
 
 	int (*prepare_transfer_hardware)(struct spi_master *master);
 	int (*prepare_transfer_hardware)(struct spi_master *master);
 	int (*transfer_one_message)(struct spi_master *master,
 	int (*transfer_one_message)(struct spi_master *master,
 				    struct spi_message *mesg);
 				    struct spi_message *mesg);
 	int (*unprepare_transfer_hardware)(struct spi_master *master);
 	int (*unprepare_transfer_hardware)(struct spi_master *master);
+	int (*prepare_message)(struct spi_master *master,
+			       struct spi_message *message);
+	int (*unprepare_message)(struct spi_master *master,
+				 struct spi_message *message);
+
+	/*
+	 * These hooks are for drivers that use a generic implementation
+	 * of transfer_one_message() provied by the core.
+	 */
+	void (*set_cs)(struct spi_device *spi, bool enable);
+	int (*transfer_one)(struct spi_master *master, struct spi_device *spi,
+			    struct spi_transfer *transfer);
 
 
 	/* gpio chip select */
 	/* gpio chip select */
 	int			*cs_gpios;
 	int			*cs_gpios;
@@ -428,12 +455,15 @@ extern int spi_master_resume(struct spi_master *master);
 /* Calls the driver make to interact with the message queue */
 /* Calls the driver make to interact with the message queue */
 extern struct spi_message *spi_get_next_queued_message(struct spi_master *master);
 extern struct spi_message *spi_get_next_queued_message(struct spi_master *master);
 extern void spi_finalize_current_message(struct spi_master *master);
 extern void spi_finalize_current_message(struct spi_master *master);
+extern void spi_finalize_current_transfer(struct spi_master *master);
 
 
 /* the spi driver core manages memory for the spi_master classdev */
 /* the spi driver core manages memory for the spi_master classdev */
 extern struct spi_master *
 extern struct spi_master *
 spi_alloc_master(struct device *host, unsigned size);
 spi_alloc_master(struct device *host, unsigned size);
 
 
 extern int spi_register_master(struct spi_master *master);
 extern int spi_register_master(struct spi_master *master);
+extern int devm_spi_register_master(struct device *dev,
+				    struct spi_master *master);
 extern void spi_unregister_master(struct spi_master *master);
 extern void spi_unregister_master(struct spi_master *master);
 
 
 extern struct spi_master *spi_busnum_to_master(u16 busnum);
 extern struct spi_master *spi_busnum_to_master(u16 busnum);
@@ -823,6 +853,33 @@ static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd)
 	return (status < 0) ? status : result;
 	return (status < 0) ? status : result;
 }
 }
 
 
+/**
+ * spi_w8r16be - SPI synchronous 8 bit write followed by 16 bit big-endian read
+ * @spi: device with which data will be exchanged
+ * @cmd: command to be written before data is read back
+ * Context: can sleep
+ *
+ * This returns the (unsigned) sixteen bit number returned by the device in cpu
+ * endianness, or else a negative error code. Callable only from contexts that
+ * can sleep.
+ *
+ * This function is similar to spi_w8r16, with the exception that it will
+ * convert the read 16 bit data word from big-endian to native endianness.
+ *
+ */
+static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd)
+
+{
+	ssize_t status;
+	__be16 result;
+
+	status = spi_write_then_read(spi, &cmd, 1, &result, 2);
+	if (status < 0)
+		return status;
+
+	return be16_to_cpu(result);
+}
+
 /*---------------------------------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
 
 
 /*
 /*

+ 156 - 0
include/trace/events/spi.h

@@ -0,0 +1,156 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spi
+
+#if !defined(_TRACE_SPI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPI_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(spi_master,
+
+	TP_PROTO(struct spi_master *master),
+
+	TP_ARGS(master),
+
+	TP_STRUCT__entry(
+		__field(        int,           bus_num             )
+	),
+
+	TP_fast_assign(
+		__entry->bus_num = master->bus_num;
+	),
+
+	TP_printk("spi%d", (int)__entry->bus_num)
+
+);
+
+DEFINE_EVENT(spi_master, spi_master_idle,
+
+	TP_PROTO(struct spi_master *master),
+
+	TP_ARGS(master)
+
+);
+
+DEFINE_EVENT(spi_master, spi_master_busy,
+
+	TP_PROTO(struct spi_master *master),
+
+	TP_ARGS(master)
+
+);
+
+DECLARE_EVENT_CLASS(spi_message,
+
+	TP_PROTO(struct spi_message *msg),
+
+	TP_ARGS(msg),
+
+	TP_STRUCT__entry(
+		__field(        int,            bus_num         )
+		__field(        int,            chip_select     )
+		__field(        struct spi_message *,   msg     )
+	),
+
+	TP_fast_assign(
+		__entry->bus_num = msg->spi->master->bus_num;
+		__entry->chip_select = msg->spi->chip_select;
+		__entry->msg = msg;
+	),
+
+        TP_printk("spi%d.%d %p", (int)__entry->bus_num,
+		  (int)__entry->chip_select,
+		  (struct spi_message *)__entry->msg)
+);
+
+DEFINE_EVENT(spi_message, spi_message_submit,
+
+	TP_PROTO(struct spi_message *msg),
+
+	TP_ARGS(msg)
+
+);
+
+DEFINE_EVENT(spi_message, spi_message_start,
+
+	TP_PROTO(struct spi_message *msg),
+
+	TP_ARGS(msg)
+
+);
+
+TRACE_EVENT(spi_message_done,
+
+	TP_PROTO(struct spi_message *msg),
+
+	TP_ARGS(msg),
+
+	TP_STRUCT__entry(
+		__field(        int,            bus_num         )
+		__field(        int,            chip_select     )
+		__field(        struct spi_message *,   msg     )
+		__field(        unsigned,       frame           )
+		__field(        unsigned,       actual          )
+	),
+
+	TP_fast_assign(
+		__entry->bus_num = msg->spi->master->bus_num;
+		__entry->chip_select = msg->spi->chip_select;
+		__entry->msg = msg;
+		__entry->frame = msg->frame_length;
+		__entry->actual = msg->actual_length;
+	),
+
+        TP_printk("spi%d.%d %p len=%u/%u", (int)__entry->bus_num,
+		  (int)__entry->chip_select,
+		  (struct spi_message *)__entry->msg,
+                  (unsigned)__entry->actual, (unsigned)__entry->frame)
+);
+
+DECLARE_EVENT_CLASS(spi_transfer,
+
+	TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+	TP_ARGS(msg, xfer),
+
+	TP_STRUCT__entry(
+		__field(        int,            bus_num         )
+		__field(        int,            chip_select     )
+		__field(        struct spi_transfer *,   xfer   )
+		__field(        int,            len             )
+	),
+
+	TP_fast_assign(
+		__entry->bus_num = msg->spi->master->bus_num;
+		__entry->chip_select = msg->spi->chip_select;
+		__entry->xfer = xfer;
+		__entry->len = xfer->len;
+	),
+
+        TP_printk("spi%d.%d %p len=%d", (int)__entry->bus_num,
+		  (int)__entry->chip_select,
+		  (struct spi_message *)__entry->xfer,
+		  (int)__entry->len)
+);
+
+DEFINE_EVENT(spi_transfer, spi_transfer_start,
+
+	TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+	TP_ARGS(msg, xfer)
+
+);
+
+DEFINE_EVENT(spi_transfer, spi_transfer_stop,
+
+	TP_PROTO(struct spi_message *msg, struct spi_transfer *xfer),
+
+	TP_ARGS(msg, xfer)
+
+);
+
+#endif /* _TRACE_POWER_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>