diff options
author | Mark Brown <broonie@linaro.org> | 2013-09-01 08:49:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-09-01 08:49:06 -0400 |
commit | 85cac431329bd09f7d30d489591d7af0d658b008 (patch) | |
tree | 8e81e687c9104c297b9d985e2c5f37f05a6e4b83 /drivers/spi | |
parent | 793b3cb6acc081e557dabcf11ce781d64dafb4d4 (diff) | |
parent | b6460366fbadc160604f50047d0394c7fc39ceab (diff) |
Merge remote-tracking branch 'spi/topic/qspi' into spi-next
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 8 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi-bcm63xx.c | 21 | ||||
-rw-r--r-- | drivers/spi/spi-coldfire-qspi.c | 21 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 20 | ||||
-rw-r--r-- | drivers/spi/spi-pl022.c | 21 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 12 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 4 | ||||
-rw-r--r-- | drivers/spi/spi-sh-hspi.c | 18 | ||||
-rw-r--r-- | drivers/spi/spi-tegra114.c | 10 | ||||
-rw-r--r-- | drivers/spi/spi-tegra20-sflash.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-ti-qspi.c | 574 | ||||
-rw-r--r-- | drivers/spi/spi.c | 118 |
14 files changed, 710 insertions, 134 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8aad2c1dc33d..f552c89abdd4 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -306,6 +306,14 @@ config SPI_OMAP24XX | |||
306 | SPI master controller for OMAP24XX and later Multichannel SPI | 306 | SPI master controller for OMAP24XX and later Multichannel SPI |
307 | (McSPI) modules. | 307 | (McSPI) modules. |
308 | 308 | ||
309 | config SPI_TI_QSPI | ||
310 | tristate "DRA7xxx QSPI controller support" | ||
311 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
312 | help | ||
313 | QSPI master controller for DRA7xxx used for flash devices. | ||
314 | This device supports single, dual and quad read support, while | ||
315 | it only supports single write mode. | ||
316 | |||
309 | config SPI_OMAP_100K | 317 | config SPI_OMAP_100K |
310 | tristate "OMAP SPI 100K" | 318 | tristate "OMAP SPI 100K" |
311 | depends on ARCH_OMAP850 || ARCH_OMAP730 || COMPILE_TEST | 319 | depends on ARCH_OMAP850 || ARCH_OMAP730 || COMPILE_TEST |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 985d7bad7932..ab8d8644af0e 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_OCTEON) += spi-octeon.o | |||
49 | obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o | 49 | obj-$(CONFIG_SPI_OMAP_UWIRE) += spi-omap-uwire.o |
50 | obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o | 50 | obj-$(CONFIG_SPI_OMAP_100K) += spi-omap-100k.o |
51 | obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o | 51 | obj-$(CONFIG_SPI_OMAP24XX) += spi-omap2-mcspi.o |
52 | obj-$(CONFIG_SPI_TI_QSPI) += spi-ti-qspi.o | ||
52 | obj-$(CONFIG_SPI_ORION) += spi-orion.o | 53 | obj-$(CONFIG_SPI_ORION) += spi-orion.o |
53 | obj-$(CONFIG_SPI_PL022) += spi-pl022.o | 54 | obj-$(CONFIG_SPI_PL022) += spi-pl022.o |
54 | obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o | 55 | obj-$(CONFIG_SPI_PPC4xx) += spi-ppc4xx.o |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index de197f72e082..536b0e363826 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -231,24 +231,6 @@ static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first, | |||
231 | return 0; | 231 | return 0; |
232 | } | 232 | } |
233 | 233 | ||
234 | static int bcm63xx_spi_prepare_transfer(struct spi_master *master) | ||
235 | { | ||
236 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); | ||
237 | |||
238 | pm_runtime_get_sync(&bs->pdev->dev); | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) | ||
244 | { | ||
245 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); | ||
246 | |||
247 | pm_runtime_put(&bs->pdev->dev); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int bcm63xx_spi_transfer_one(struct spi_master *master, | 234 | static int bcm63xx_spi_transfer_one(struct spi_master *master, |
253 | struct spi_message *m) | 235 | struct spi_message *m) |
254 | { | 236 | { |
@@ -406,11 +388,10 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) | |||
406 | 388 | ||
407 | master->bus_num = pdata->bus_num; | 389 | master->bus_num = pdata->bus_num; |
408 | master->num_chipselect = pdata->num_chipselect; | 390 | master->num_chipselect = pdata->num_chipselect; |
409 | master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; | ||
410 | master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; | ||
411 | master->transfer_one_message = bcm63xx_spi_transfer_one; | 391 | master->transfer_one_message = bcm63xx_spi_transfer_one; |
412 | master->mode_bits = MODEBITS; | 392 | master->mode_bits = MODEBITS; |
413 | master->bits_per_word_mask = SPI_BPW_MASK(8); | 393 | master->bits_per_word_mask = SPI_BPW_MASK(8); |
394 | master->auto_runtime_pm = true; | ||
414 | bs->msg_type_shift = pdata->msg_type_shift; | 395 | bs->msg_type_shift = pdata->msg_type_shift; |
415 | bs->msg_ctl_width = pdata->msg_ctl_width; | 396 | bs->msg_ctl_width = pdata->msg_ctl_width; |
416 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); | 397 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); |
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 8e07928cadb3..cc5b75d10c38 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
@@ -354,24 +354,6 @@ static int mcfqspi_transfer_one_message(struct spi_master *master, | |||
354 | 354 | ||
355 | } | 355 | } |
356 | 356 | ||
357 | static int mcfqspi_prepare_transfer_hw(struct spi_master *master) | ||
358 | { | ||
359 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | ||
360 | |||
361 | pm_runtime_get_sync(mcfqspi->dev); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int mcfqspi_unprepare_transfer_hw(struct spi_master *master) | ||
367 | { | ||
368 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | ||
369 | |||
370 | pm_runtime_put_sync(mcfqspi->dev); | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static int mcfqspi_setup(struct spi_device *spi) | 357 | static int mcfqspi_setup(struct spi_device *spi) |
376 | { | 358 | { |
377 | if (spi->chip_select >= spi->master->num_chipselect) { | 359 | if (spi->chip_select >= spi->master->num_chipselect) { |
@@ -473,8 +455,7 @@ static int mcfqspi_probe(struct platform_device *pdev) | |||
473 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); | 455 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); |
474 | master->setup = mcfqspi_setup; | 456 | master->setup = mcfqspi_setup; |
475 | master->transfer_one_message = mcfqspi_transfer_one_message; | 457 | master->transfer_one_message = mcfqspi_transfer_one_message; |
476 | master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw; | 458 | master->auto_runtime_pm = true; |
477 | master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw; | ||
478 | 459 | ||
479 | platform_set_drvdata(pdev, master); | 460 | platform_set_drvdata(pdev, master); |
480 | 461 | ||
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index fc190a5a0bad..ed4af4708d9a 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -335,23 +335,6 @@ static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) | |||
335 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | 335 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); |
336 | } | 336 | } |
337 | 337 | ||
338 | static int omap2_prepare_transfer(struct spi_master *master) | ||
339 | { | ||
340 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
341 | |||
342 | pm_runtime_get_sync(mcspi->dev); | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | static int omap2_unprepare_transfer(struct spi_master *master) | ||
347 | { | ||
348 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
349 | |||
350 | pm_runtime_mark_last_busy(mcspi->dev); | ||
351 | pm_runtime_put_autosuspend(mcspi->dev); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | 338 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) |
356 | { | 339 | { |
357 | unsigned long timeout; | 340 | unsigned long timeout; |
@@ -1318,8 +1301,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
1318 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1301 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1319 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); | 1302 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
1320 | master->setup = omap2_mcspi_setup; | 1303 | master->setup = omap2_mcspi_setup; |
1321 | master->prepare_transfer_hardware = omap2_prepare_transfer; | 1304 | master->auto_runtime_pm = true; |
1322 | master->unprepare_transfer_hardware = omap2_unprepare_transfer; | ||
1323 | master->transfer_one_message = omap2_mcspi_transfer_one_message; | 1305 | master->transfer_one_message = omap2_mcspi_transfer_one_message; |
1324 | master->cleanup = omap2_mcspi_cleanup; | 1306 | master->cleanup = omap2_mcspi_cleanup; |
1325 | master->dev.of_node = node; | 1307 | master->dev.of_node = node; |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 5a9e05e20bb5..9c511a954d21 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1555,18 +1555,6 @@ static int pl022_transfer_one_message(struct spi_master *master, | |||
1555 | return 0; | 1555 | return 0; |
1556 | } | 1556 | } |
1557 | 1557 | ||
1558 | static int pl022_prepare_transfer_hardware(struct spi_master *master) | ||
1559 | { | ||
1560 | struct pl022 *pl022 = spi_master_get_devdata(master); | ||
1561 | |||
1562 | /* | ||
1563 | * Just make sure we have all we need to run the transfer by syncing | ||
1564 | * with the runtime PM framework. | ||
1565 | */ | ||
1566 | pm_runtime_get_sync(&pl022->adev->dev); | ||
1567 | return 0; | ||
1568 | } | ||
1569 | |||
1570 | static int pl022_unprepare_transfer_hardware(struct spi_master *master) | 1558 | static int pl022_unprepare_transfer_hardware(struct spi_master *master) |
1571 | { | 1559 | { |
1572 | struct pl022 *pl022 = spi_master_get_devdata(master); | 1560 | struct pl022 *pl022 = spi_master_get_devdata(master); |
@@ -1575,13 +1563,6 @@ static int pl022_unprepare_transfer_hardware(struct spi_master *master) | |||
1575 | writew((readw(SSP_CR1(pl022->virtbase)) & | 1563 | writew((readw(SSP_CR1(pl022->virtbase)) & |
1576 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | 1564 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); |
1577 | 1565 | ||
1578 | if (pl022->master_info->autosuspend_delay > 0) { | ||
1579 | pm_runtime_mark_last_busy(&pl022->adev->dev); | ||
1580 | pm_runtime_put_autosuspend(&pl022->adev->dev); | ||
1581 | } else { | ||
1582 | pm_runtime_put(&pl022->adev->dev); | ||
1583 | } | ||
1584 | |||
1585 | return 0; | 1566 | return 0; |
1586 | } | 1567 | } |
1587 | 1568 | ||
@@ -2140,7 +2121,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2140 | master->num_chipselect = num_cs; | 2121 | master->num_chipselect = num_cs; |
2141 | master->cleanup = pl022_cleanup; | 2122 | master->cleanup = pl022_cleanup; |
2142 | master->setup = pl022_setup; | 2123 | master->setup = pl022_setup; |
2143 | master->prepare_transfer_hardware = pl022_prepare_transfer_hardware; | 2124 | master->auto_runtime_pm = true; |
2144 | master->transfer_one_message = pl022_transfer_one_message; | 2125 | master->transfer_one_message = pl022_transfer_one_message; |
2145 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; | 2126 | master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware; |
2146 | master->rt = platform_info->rt; | 2127 | master->rt = platform_info->rt; |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index e0fd6f63c93e..2eb06ee0b326 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
@@ -811,14 +811,6 @@ static int pxa2xx_spi_transfer_one_message(struct spi_master *master, | |||
811 | return 0; | 811 | return 0; |
812 | } | 812 | } |
813 | 813 | ||
814 | static int pxa2xx_spi_prepare_transfer(struct spi_master *master) | ||
815 | { | ||
816 | struct driver_data *drv_data = spi_master_get_devdata(master); | ||
817 | |||
818 | pm_runtime_get_sync(&drv_data->pdev->dev); | ||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) | 814 | static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) |
823 | { | 815 | { |
824 | struct driver_data *drv_data = spi_master_get_devdata(master); | 816 | struct driver_data *drv_data = spi_master_get_devdata(master); |
@@ -827,8 +819,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_master *master) | |||
827 | write_SSCR0(read_SSCR0(drv_data->ioaddr) & ~SSCR0_SSE, | 819 | write_SSCR0(read_SSCR0(drv_data->ioaddr) & ~SSCR0_SSE, |
828 | drv_data->ioaddr); | 820 | drv_data->ioaddr); |
829 | 821 | ||
830 | pm_runtime_mark_last_busy(&drv_data->pdev->dev); | ||
831 | pm_runtime_put_autosuspend(&drv_data->pdev->dev); | ||
832 | return 0; | 822 | return 0; |
833 | } | 823 | } |
834 | 824 | ||
@@ -1141,8 +1131,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) | |||
1141 | master->cleanup = cleanup; | 1131 | master->cleanup = cleanup; |
1142 | master->setup = setup; | 1132 | master->setup = setup; |
1143 | master->transfer_one_message = pxa2xx_spi_transfer_one_message; | 1133 | master->transfer_one_message = pxa2xx_spi_transfer_one_message; |
1144 | master->prepare_transfer_hardware = pxa2xx_spi_prepare_transfer; | ||
1145 | master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; | 1134 | master->unprepare_transfer_hardware = pxa2xx_spi_unprepare_transfer; |
1135 | master->auto_runtime_pm = true; | ||
1146 | 1136 | ||
1147 | drv_data->ssp_type = ssp->type; | 1137 | drv_data->ssp_type = ssp->type; |
1148 | drv_data->null_dma_buf = (u32 *)PTR_ALIGN(&drv_data[1], DMA_ALIGNMENT); | 1138 | drv_data->null_dma_buf = (u32 *)PTR_ALIGN(&drv_data[1], DMA_ALIGNMENT); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 2465d6d35b06..c5bc96123c1b 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -356,8 +356,6 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi) | |||
356 | while (!is_polling(sdd) && !acquire_dma(sdd)) | 356 | while (!is_polling(sdd) && !acquire_dma(sdd)) |
357 | usleep_range(10000, 11000); | 357 | usleep_range(10000, 11000); |
358 | 358 | ||
359 | pm_runtime_get_sync(&sdd->pdev->dev); | ||
360 | |||
361 | return 0; | 359 | return 0; |
362 | } | 360 | } |
363 | 361 | ||
@@ -372,7 +370,6 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi) | |||
372 | sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, | 370 | sdd->ops->release((enum dma_ch)sdd->tx_dma.ch, |
373 | &s3c64xx_spi_dma_client); | 371 | &s3c64xx_spi_dma_client); |
374 | } | 372 | } |
375 | pm_runtime_put(&sdd->pdev->dev); | ||
376 | 373 | ||
377 | return 0; | 374 | return 0; |
378 | } | 375 | } |
@@ -1395,6 +1392,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) | |||
1395 | SPI_BPW_MASK(8); | 1392 | SPI_BPW_MASK(8); |
1396 | /* the spi->mode bits understood by this driver: */ | 1393 | /* the spi->mode bits understood by this driver: */ |
1397 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1394 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1395 | master->auto_runtime_pm = true; | ||
1398 | 1396 | ||
1399 | sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res); | 1397 | sdd->regs = devm_ioremap_resource(&pdev->dev, mem_res); |
1400 | if (IS_ERR(sdd->regs)) { | 1398 | if (IS_ERR(sdd->regs)) { |
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 716edf999538..b95d6a9fb80e 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c | |||
@@ -99,21 +99,6 @@ static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val) | |||
99 | /* | 99 | /* |
100 | * spi master function | 100 | * spi master function |
101 | */ | 101 | */ |
102 | static int hspi_prepare_transfer(struct spi_master *master) | ||
103 | { | ||
104 | struct hspi_priv *hspi = spi_master_get_devdata(master); | ||
105 | |||
106 | pm_runtime_get_sync(hspi->dev); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int hspi_unprepare_transfer(struct spi_master *master) | ||
111 | { | ||
112 | struct hspi_priv *hspi = spi_master_get_devdata(master); | ||
113 | |||
114 | pm_runtime_put_sync(hspi->dev); | ||
115 | return 0; | ||
116 | } | ||
117 | 102 | ||
118 | #define hspi_hw_cs_enable(hspi) hspi_hw_cs_ctrl(hspi, 0) | 103 | #define hspi_hw_cs_enable(hspi) hspi_hw_cs_ctrl(hspi, 0) |
119 | #define hspi_hw_cs_disable(hspi) hspi_hw_cs_ctrl(hspi, 1) | 104 | #define hspi_hw_cs_disable(hspi) hspi_hw_cs_ctrl(hspi, 1) |
@@ -316,9 +301,8 @@ static int hspi_probe(struct platform_device *pdev) | |||
316 | master->setup = hspi_setup; | 301 | master->setup = hspi_setup; |
317 | master->cleanup = hspi_cleanup; | 302 | master->cleanup = hspi_cleanup; |
318 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 303 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
319 | master->prepare_transfer_hardware = hspi_prepare_transfer; | 304 | master->auto_runtime_pm = true; |
320 | master->transfer_one_message = hspi_transfer_one_message; | 305 | master->transfer_one_message = hspi_transfer_one_message; |
321 | master->unprepare_transfer_hardware = hspi_unprepare_transfer; | ||
322 | ret = spi_register_master(master); | 306 | ret = spi_register_master(master); |
323 | if (ret < 0) { | 307 | if (ret < 0) { |
324 | dev_err(&pdev->dev, "spi_register_master error.\n"); | 308 | dev_err(&pdev->dev, "spi_register_master error.\n"); |
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index e8f542ab8935..c14e30c8af2e 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c | |||
@@ -816,14 +816,6 @@ static int tegra_spi_transfer_one_message(struct spi_master *master, | |||
816 | msg->status = 0; | 816 | msg->status = 0; |
817 | msg->actual_length = 0; | 817 | msg->actual_length = 0; |
818 | 818 | ||
819 | ret = pm_runtime_get_sync(tspi->dev); | ||
820 | if (ret < 0) { | ||
821 | dev_err(tspi->dev, "runtime PM get failed: %d\n", ret); | ||
822 | msg->status = ret; | ||
823 | spi_finalize_current_message(master); | ||
824 | return ret; | ||
825 | } | ||
826 | |||
827 | single_xfer = list_is_singular(&msg->transfers); | 819 | single_xfer = list_is_singular(&msg->transfers); |
828 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 820 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
829 | INIT_COMPLETION(tspi->xfer_completion); | 821 | INIT_COMPLETION(tspi->xfer_completion); |
@@ -859,7 +851,6 @@ static int tegra_spi_transfer_one_message(struct spi_master *master, | |||
859 | ret = 0; | 851 | ret = 0; |
860 | exit: | 852 | exit: |
861 | tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); | 853 | tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); |
862 | pm_runtime_put(tspi->dev); | ||
863 | msg->status = ret; | 854 | msg->status = ret; |
864 | spi_finalize_current_message(master); | 855 | spi_finalize_current_message(master); |
865 | return ret; | 856 | return ret; |
@@ -1053,6 +1044,7 @@ static int tegra_spi_probe(struct platform_device *pdev) | |||
1053 | master->transfer_one_message = tegra_spi_transfer_one_message; | 1044 | master->transfer_one_message = tegra_spi_transfer_one_message; |
1054 | master->num_chipselect = MAX_CHIP_SELECT; | 1045 | master->num_chipselect = MAX_CHIP_SELECT; |
1055 | master->bus_num = -1; | 1046 | master->bus_num = -1; |
1047 | master->auto_runtime_pm = true; | ||
1056 | 1048 | ||
1057 | tspi->master = master; | 1049 | tspi->master = master; |
1058 | tspi->dev = &pdev->dev; | 1050 | tspi->dev = &pdev->dev; |
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c index c1d5d95e70ea..1d814dc6e000 100644 --- a/drivers/spi/spi-tegra20-sflash.c +++ b/drivers/spi/spi-tegra20-sflash.c | |||
@@ -335,12 +335,6 @@ static int tegra_sflash_transfer_one_message(struct spi_master *master, | |||
335 | struct spi_device *spi = msg->spi; | 335 | struct spi_device *spi = msg->spi; |
336 | int ret; | 336 | int ret; |
337 | 337 | ||
338 | ret = pm_runtime_get_sync(tsd->dev); | ||
339 | if (ret < 0) { | ||
340 | dev_err(tsd->dev, "pm_runtime_get() failed, err = %d\n", ret); | ||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | msg->status = 0; | 338 | msg->status = 0; |
345 | msg->actual_length = 0; | 339 | msg->actual_length = 0; |
346 | single_xfer = list_is_singular(&msg->transfers); | 340 | single_xfer = list_is_singular(&msg->transfers); |
@@ -380,7 +374,6 @@ exit: | |||
380 | tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); | 374 | tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND); |
381 | msg->status = ret; | 375 | msg->status = ret; |
382 | spi_finalize_current_message(master); | 376 | spi_finalize_current_message(master); |
383 | pm_runtime_put(tsd->dev); | ||
384 | return ret; | 377 | return ret; |
385 | } | 378 | } |
386 | 379 | ||
@@ -477,6 +470,7 @@ static int tegra_sflash_probe(struct platform_device *pdev) | |||
477 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 470 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
478 | master->setup = tegra_sflash_setup; | 471 | master->setup = tegra_sflash_setup; |
479 | master->transfer_one_message = tegra_sflash_transfer_one_message; | 472 | master->transfer_one_message = tegra_sflash_transfer_one_message; |
473 | master->auto_runtime_pm = true; | ||
480 | master->num_chipselect = MAX_CHIP_SELECT; | 474 | master->num_chipselect = MAX_CHIP_SELECT; |
481 | master->bus_num = -1; | 475 | master->bus_num = -1; |
482 | 476 | ||
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 80490cc11ce5..c70353672a23 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
@@ -836,11 +836,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, | |||
836 | 836 | ||
837 | msg->status = 0; | 837 | msg->status = 0; |
838 | msg->actual_length = 0; | 838 | msg->actual_length = 0; |
839 | ret = pm_runtime_get_sync(tspi->dev); | ||
840 | if (ret < 0) { | ||
841 | dev_err(tspi->dev, "runtime get failed: %d\n", ret); | ||
842 | goto done; | ||
843 | } | ||
844 | 839 | ||
845 | single_xfer = list_is_singular(&msg->transfers); | 840 | single_xfer = list_is_singular(&msg->transfers); |
846 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 841 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
@@ -878,8 +873,6 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, | |||
878 | exit: | 873 | exit: |
879 | tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); | 874 | tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); |
880 | tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); | 875 | tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); |
881 | pm_runtime_put(tspi->dev); | ||
882 | done: | ||
883 | msg->status = ret; | 876 | msg->status = ret; |
884 | spi_finalize_current_message(master); | 877 | spi_finalize_current_message(master); |
885 | return ret; | 878 | return ret; |
@@ -1086,6 +1079,7 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
1086 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 1079 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
1087 | master->setup = tegra_slink_setup; | 1080 | master->setup = tegra_slink_setup; |
1088 | master->transfer_one_message = tegra_slink_transfer_one_message; | 1081 | master->transfer_one_message = tegra_slink_transfer_one_message; |
1082 | master->auto_runtime_pm = true; | ||
1089 | master->num_chipselect = MAX_CHIP_SELECT; | 1083 | master->num_chipselect = MAX_CHIP_SELECT; |
1090 | master->bus_num = -1; | 1084 | master->bus_num = -1; |
1091 | 1085 | ||
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c new file mode 100644 index 000000000000..e12d962a289f --- /dev/null +++ b/drivers/spi/spi-ti-qspi.c | |||
@@ -0,0 +1,574 @@ | |||
1 | /* | ||
2 | * TI QSPI driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com | ||
5 | * Author: Sourav Poddar <sourav.poddar@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GPLv2. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/dmaengine.h> | ||
24 | #include <linux/omap-dma.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/pm_runtime.h> | ||
31 | #include <linux/of.h> | ||
32 | #include <linux/of_device.h> | ||
33 | #include <linux/pinctrl/consumer.h> | ||
34 | |||
35 | #include <linux/spi/spi.h> | ||
36 | |||
37 | struct ti_qspi_regs { | ||
38 | u32 clkctrl; | ||
39 | }; | ||
40 | |||
41 | struct ti_qspi { | ||
42 | struct completion transfer_complete; | ||
43 | |||
44 | /* IRQ synchronization */ | ||
45 | spinlock_t lock; | ||
46 | |||
47 | /* list synchronization */ | ||
48 | struct mutex list_lock; | ||
49 | |||
50 | struct spi_master *master; | ||
51 | void __iomem *base; | ||
52 | struct clk *fclk; | ||
53 | struct device *dev; | ||
54 | |||
55 | struct ti_qspi_regs ctx_reg; | ||
56 | |||
57 | u32 spi_max_frequency; | ||
58 | u32 cmd; | ||
59 | u32 dc; | ||
60 | u32 stat; | ||
61 | }; | ||
62 | |||
63 | #define QSPI_PID (0x0) | ||
64 | #define QSPI_SYSCONFIG (0x10) | ||
65 | #define QSPI_INTR_STATUS_RAW_SET (0x20) | ||
66 | #define QSPI_INTR_STATUS_ENABLED_CLEAR (0x24) | ||
67 | #define QSPI_INTR_ENABLE_SET_REG (0x28) | ||
68 | #define QSPI_INTR_ENABLE_CLEAR_REG (0x2c) | ||
69 | #define QSPI_SPI_CLOCK_CNTRL_REG (0x40) | ||
70 | #define QSPI_SPI_DC_REG (0x44) | ||
71 | #define QSPI_SPI_CMD_REG (0x48) | ||
72 | #define QSPI_SPI_STATUS_REG (0x4c) | ||
73 | #define QSPI_SPI_DATA_REG (0x50) | ||
74 | #define QSPI_SPI_SETUP0_REG (0x54) | ||
75 | #define QSPI_SPI_SWITCH_REG (0x64) | ||
76 | #define QSPI_SPI_SETUP1_REG (0x58) | ||
77 | #define QSPI_SPI_SETUP2_REG (0x5c) | ||
78 | #define QSPI_SPI_SETUP3_REG (0x60) | ||
79 | #define QSPI_SPI_DATA_REG_1 (0x68) | ||
80 | #define QSPI_SPI_DATA_REG_2 (0x6c) | ||
81 | #define QSPI_SPI_DATA_REG_3 (0x70) | ||
82 | |||
83 | #define QSPI_COMPLETION_TIMEOUT msecs_to_jiffies(2000) | ||
84 | |||
85 | #define QSPI_FCLK 192000000 | ||
86 | |||
87 | /* Clock Control */ | ||
88 | #define QSPI_CLK_EN (1 << 31) | ||
89 | #define QSPI_CLK_DIV_MAX 0xffff | ||
90 | |||
91 | /* Command */ | ||
92 | #define QSPI_EN_CS(n) (n << 28) | ||
93 | #define QSPI_WLEN(n) ((n - 1) << 19) | ||
94 | #define QSPI_3_PIN (1 << 18) | ||
95 | #define QSPI_RD_SNGL (1 << 16) | ||
96 | #define QSPI_WR_SNGL (2 << 16) | ||
97 | #define QSPI_RD_DUAL (3 << 16) | ||
98 | #define QSPI_RD_QUAD (7 << 16) | ||
99 | #define QSPI_INVAL (4 << 16) | ||
100 | #define QSPI_WC_CMD_INT_EN (1 << 14) | ||
101 | #define QSPI_FLEN(n) ((n - 1) << 0) | ||
102 | |||
103 | /* STATUS REGISTER */ | ||
104 | #define WC 0x02 | ||
105 | |||
106 | /* INTERRUPT REGISTER */ | ||
107 | #define QSPI_WC_INT_EN (1 << 1) | ||
108 | #define QSPI_WC_INT_DISABLE (1 << 1) | ||
109 | |||
110 | /* Device Control */ | ||
111 | #define QSPI_DD(m, n) (m << (3 + n * 8)) | ||
112 | #define QSPI_CKPHA(n) (1 << (2 + n * 8)) | ||
113 | #define QSPI_CSPOL(n) (1 << (1 + n * 8)) | ||
114 | #define QSPI_CKPOL(n) (1 << (n * 8)) | ||
115 | |||
116 | #define QSPI_FRAME 4096 | ||
117 | |||
118 | #define QSPI_AUTOSUSPEND_TIMEOUT 2000 | ||
119 | |||
120 | static inline unsigned long ti_qspi_read(struct ti_qspi *qspi, | ||
121 | unsigned long reg) | ||
122 | { | ||
123 | return readl(qspi->base + reg); | ||
124 | } | ||
125 | |||
126 | static inline void ti_qspi_write(struct ti_qspi *qspi, | ||
127 | unsigned long val, unsigned long reg) | ||
128 | { | ||
129 | writel(val, qspi->base + reg); | ||
130 | } | ||
131 | |||
132 | static int ti_qspi_setup(struct spi_device *spi) | ||
133 | { | ||
134 | struct ti_qspi *qspi = spi_master_get_devdata(spi->master); | ||
135 | struct ti_qspi_regs *ctx_reg = &qspi->ctx_reg; | ||
136 | int clk_div = 0, ret; | ||
137 | u32 clk_ctrl_reg, clk_rate, clk_mask; | ||
138 | |||
139 | if (spi->master->busy) { | ||
140 | dev_dbg(qspi->dev, "master busy doing other trasnfers\n"); | ||
141 | return -EBUSY; | ||
142 | } | ||
143 | |||
144 | if (!qspi->spi_max_frequency) { | ||
145 | dev_err(qspi->dev, "spi max frequency not defined\n"); | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | |||
149 | clk_rate = clk_get_rate(qspi->fclk); | ||
150 | |||
151 | clk_div = DIV_ROUND_UP(clk_rate, qspi->spi_max_frequency) - 1; | ||
152 | |||
153 | if (clk_div < 0) { | ||
154 | dev_dbg(qspi->dev, "clock divider < 0, using /1 divider\n"); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | if (clk_div > QSPI_CLK_DIV_MAX) { | ||
159 | dev_dbg(qspi->dev, "clock divider >%d , using /%d divider\n", | ||
160 | QSPI_CLK_DIV_MAX, QSPI_CLK_DIV_MAX + 1); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | |||
164 | dev_dbg(qspi->dev, "hz: %d, clock divider %d\n", | ||
165 | qspi->spi_max_frequency, clk_div); | ||
166 | |||
167 | ret = pm_runtime_get_sync(qspi->dev); | ||
168 | if (ret) { | ||
169 | dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | clk_ctrl_reg = ti_qspi_read(qspi, QSPI_SPI_CLOCK_CNTRL_REG); | ||
174 | |||
175 | clk_ctrl_reg &= ~QSPI_CLK_EN; | ||
176 | |||
177 | /* disable SCLK */ | ||
178 | ti_qspi_write(qspi, clk_ctrl_reg, QSPI_SPI_CLOCK_CNTRL_REG); | ||
179 | |||
180 | /* enable SCLK */ | ||
181 | clk_mask = QSPI_CLK_EN | clk_div; | ||
182 | ti_qspi_write(qspi, clk_mask, QSPI_SPI_CLOCK_CNTRL_REG); | ||
183 | ctx_reg->clkctrl = clk_mask; | ||
184 | |||
185 | pm_runtime_mark_last_busy(qspi->dev); | ||
186 | ret = pm_runtime_put_autosuspend(qspi->dev); | ||
187 | if (ret < 0) { | ||
188 | dev_err(qspi->dev, "pm_runtime_put_autosuspend() failed\n"); | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void ti_qspi_restore_ctx(struct ti_qspi *qspi) | ||
196 | { | ||
197 | struct ti_qspi_regs *ctx_reg = &qspi->ctx_reg; | ||
198 | |||
199 | ti_qspi_write(qspi, ctx_reg->clkctrl, QSPI_SPI_CLOCK_CNTRL_REG); | ||
200 | } | ||
201 | |||
202 | static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) | ||
203 | { | ||
204 | int wlen, count, ret; | ||
205 | unsigned int cmd; | ||
206 | const u8 *txbuf; | ||
207 | |||
208 | txbuf = t->tx_buf; | ||
209 | cmd = qspi->cmd | QSPI_WR_SNGL; | ||
210 | count = t->len; | ||
211 | wlen = t->bits_per_word; | ||
212 | |||
213 | while (count) { | ||
214 | switch (wlen) { | ||
215 | case 8: | ||
216 | dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", | ||
217 | cmd, qspi->dc, *txbuf); | ||
218 | writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG); | ||
219 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); | ||
220 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
221 | QSPI_COMPLETION_TIMEOUT); | ||
222 | if (ret == 0) { | ||
223 | dev_err(qspi->dev, "write timed out\n"); | ||
224 | return -ETIMEDOUT; | ||
225 | } | ||
226 | txbuf += 1; | ||
227 | count -= 1; | ||
228 | break; | ||
229 | case 16: | ||
230 | dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n", | ||
231 | cmd, qspi->dc, *txbuf); | ||
232 | writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); | ||
233 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); | ||
234 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
235 | QSPI_COMPLETION_TIMEOUT); | ||
236 | if (ret == 0) { | ||
237 | dev_err(qspi->dev, "write timed out\n"); | ||
238 | return -ETIMEDOUT; | ||
239 | } | ||
240 | txbuf += 2; | ||
241 | count -= 2; | ||
242 | break; | ||
243 | case 32: | ||
244 | dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n", | ||
245 | cmd, qspi->dc, *txbuf); | ||
246 | writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); | ||
247 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); | ||
248 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
249 | QSPI_COMPLETION_TIMEOUT); | ||
250 | if (ret == 0) { | ||
251 | dev_err(qspi->dev, "write timed out\n"); | ||
252 | return -ETIMEDOUT; | ||
253 | } | ||
254 | txbuf += 4; | ||
255 | count -= 4; | ||
256 | break; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) | ||
264 | { | ||
265 | int wlen, count, ret; | ||
266 | unsigned int cmd; | ||
267 | u8 *rxbuf; | ||
268 | |||
269 | rxbuf = t->rx_buf; | ||
270 | cmd = qspi->cmd; | ||
271 | switch (t->rx_nbits) { | ||
272 | case SPI_NBITS_DUAL: | ||
273 | cmd |= QSPI_RD_DUAL; | ||
274 | break; | ||
275 | case SPI_NBITS_QUAD: | ||
276 | cmd |= QSPI_RD_QUAD; | ||
277 | break; | ||
278 | default: | ||
279 | cmd |= QSPI_RD_SNGL; | ||
280 | break; | ||
281 | } | ||
282 | count = t->len; | ||
283 | wlen = t->bits_per_word; | ||
284 | |||
285 | while (count) { | ||
286 | dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); | ||
287 | ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG); | ||
288 | ret = wait_for_completion_timeout(&qspi->transfer_complete, | ||
289 | QSPI_COMPLETION_TIMEOUT); | ||
290 | if (ret == 0) { | ||
291 | dev_err(qspi->dev, "read timed out\n"); | ||
292 | return -ETIMEDOUT; | ||
293 | } | ||
294 | switch (wlen) { | ||
295 | case 8: | ||
296 | *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); | ||
297 | rxbuf += 1; | ||
298 | count -= 1; | ||
299 | break; | ||
300 | case 16: | ||
301 | *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); | ||
302 | rxbuf += 2; | ||
303 | count -= 2; | ||
304 | break; | ||
305 | case 32: | ||
306 | *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); | ||
307 | rxbuf += 4; | ||
308 | count -= 4; | ||
309 | break; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int qspi_transfer_msg(struct ti_qspi *qspi, struct spi_transfer *t) | ||
317 | { | ||
318 | int ret; | ||
319 | |||
320 | if (t->tx_buf) { | ||
321 | ret = qspi_write_msg(qspi, t); | ||
322 | if (ret) { | ||
323 | dev_dbg(qspi->dev, "Error while writing\n"); | ||
324 | return ret; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | if (t->rx_buf) { | ||
329 | ret = qspi_read_msg(qspi, t); | ||
330 | if (ret) { | ||
331 | dev_dbg(qspi->dev, "Error while reading\n"); | ||
332 | return ret; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int ti_qspi_start_transfer_one(struct spi_master *master, | ||
340 | struct spi_message *m) | ||
341 | { | ||
342 | struct ti_qspi *qspi = spi_master_get_devdata(master); | ||
343 | struct spi_device *spi = m->spi; | ||
344 | struct spi_transfer *t; | ||
345 | int status = 0, ret; | ||
346 | int frame_length; | ||
347 | |||
348 | /* setup device control reg */ | ||
349 | qspi->dc = 0; | ||
350 | |||
351 | if (spi->mode & SPI_CPHA) | ||
352 | qspi->dc |= QSPI_CKPHA(spi->chip_select); | ||
353 | if (spi->mode & SPI_CPOL) | ||
354 | qspi->dc |= QSPI_CKPOL(spi->chip_select); | ||
355 | if (spi->mode & SPI_CS_HIGH) | ||
356 | qspi->dc |= QSPI_CSPOL(spi->chip_select); | ||
357 | |||
358 | frame_length = (m->frame_length << 3) / spi->bits_per_word; | ||
359 | |||
360 | frame_length = clamp(frame_length, 0, QSPI_FRAME); | ||
361 | |||
362 | /* setup command reg */ | ||
363 | qspi->cmd = 0; | ||
364 | qspi->cmd |= QSPI_EN_CS(spi->chip_select); | ||
365 | qspi->cmd |= QSPI_FLEN(frame_length); | ||
366 | qspi->cmd |= QSPI_WC_CMD_INT_EN; | ||
367 | |||
368 | ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); | ||
369 | ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG); | ||
370 | |||
371 | mutex_lock(&qspi->list_lock); | ||
372 | |||
373 | list_for_each_entry(t, &m->transfers, transfer_list) { | ||
374 | qspi->cmd |= QSPI_WLEN(t->bits_per_word); | ||
375 | |||
376 | ret = qspi_transfer_msg(qspi, t); | ||
377 | if (ret) { | ||
378 | dev_dbg(qspi->dev, "transfer message failed\n"); | ||
379 | mutex_unlock(&qspi->list_lock); | ||
380 | return -EINVAL; | ||
381 | } | ||
382 | |||
383 | m->actual_length += t->len; | ||
384 | } | ||
385 | |||
386 | mutex_unlock(&qspi->list_lock); | ||
387 | |||
388 | m->status = status; | ||
389 | spi_finalize_current_message(master); | ||
390 | |||
391 | ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG); | ||
392 | |||
393 | return status; | ||
394 | } | ||
395 | |||
396 | static irqreturn_t ti_qspi_isr(int irq, void *dev_id) | ||
397 | { | ||
398 | struct ti_qspi *qspi = dev_id; | ||
399 | u16 int_stat; | ||
400 | |||
401 | irqreturn_t ret = IRQ_HANDLED; | ||
402 | |||
403 | spin_lock(&qspi->lock); | ||
404 | |||
405 | int_stat = ti_qspi_read(qspi, QSPI_INTR_STATUS_ENABLED_CLEAR); | ||
406 | qspi->stat = ti_qspi_read(qspi, QSPI_SPI_STATUS_REG); | ||
407 | |||
408 | if (!int_stat) { | ||
409 | dev_dbg(qspi->dev, "No IRQ triggered\n"); | ||
410 | ret = IRQ_NONE; | ||
411 | goto out; | ||
412 | } | ||
413 | |||
414 | ret = IRQ_WAKE_THREAD; | ||
415 | |||
416 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, QSPI_INTR_ENABLE_CLEAR_REG); | ||
417 | ti_qspi_write(qspi, QSPI_WC_INT_DISABLE, | ||
418 | QSPI_INTR_STATUS_ENABLED_CLEAR); | ||
419 | |||
420 | out: | ||
421 | spin_unlock(&qspi->lock); | ||
422 | |||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | static irqreturn_t ti_qspi_threaded_isr(int this_irq, void *dev_id) | ||
427 | { | ||
428 | struct ti_qspi *qspi = dev_id; | ||
429 | unsigned long flags; | ||
430 | |||
431 | spin_lock_irqsave(&qspi->lock, flags); | ||
432 | |||
433 | if (qspi->stat & WC) | ||
434 | complete(&qspi->transfer_complete); | ||
435 | |||
436 | spin_unlock_irqrestore(&qspi->lock, flags); | ||
437 | |||
438 | ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG); | ||
439 | |||
440 | return IRQ_HANDLED; | ||
441 | } | ||
442 | |||
443 | static int ti_qspi_runtime_resume(struct device *dev) | ||
444 | { | ||
445 | struct ti_qspi *qspi; | ||
446 | struct spi_master *master; | ||
447 | |||
448 | master = dev_get_drvdata(dev); | ||
449 | qspi = spi_master_get_devdata(master); | ||
450 | ti_qspi_restore_ctx(qspi); | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static const struct of_device_id ti_qspi_match[] = { | ||
456 | {.compatible = "ti,dra7xxx-qspi" }, | ||
457 | {.compatible = "ti,am4372-qspi" }, | ||
458 | {}, | ||
459 | }; | ||
460 | MODULE_DEVICE_TABLE(of, ti_qspi_match); | ||
461 | |||
462 | static int ti_qspi_probe(struct platform_device *pdev) | ||
463 | { | ||
464 | struct ti_qspi *qspi; | ||
465 | struct spi_master *master; | ||
466 | struct resource *r; | ||
467 | struct device_node *np = pdev->dev.of_node; | ||
468 | u32 max_freq; | ||
469 | int ret = 0, num_cs, irq; | ||
470 | |||
471 | master = spi_alloc_master(&pdev->dev, sizeof(*qspi)); | ||
472 | if (!master) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | master->mode_bits = SPI_CPOL | SPI_CPHA; | ||
476 | |||
477 | master->bus_num = -1; | ||
478 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
479 | master->setup = ti_qspi_setup; | ||
480 | master->auto_runtime_pm = true; | ||
481 | master->transfer_one_message = ti_qspi_start_transfer_one; | ||
482 | master->dev.of_node = pdev->dev.of_node; | ||
483 | master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); | ||
484 | |||
485 | if (!of_property_read_u32(np, "num-cs", &num_cs)) | ||
486 | master->num_chipselect = num_cs; | ||
487 | |||
488 | platform_set_drvdata(pdev, master); | ||
489 | |||
490 | qspi = spi_master_get_devdata(master); | ||
491 | qspi->master = master; | ||
492 | qspi->dev = &pdev->dev; | ||
493 | |||
494 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
495 | |||
496 | irq = platform_get_irq(pdev, 0); | ||
497 | if (irq < 0) { | ||
498 | dev_err(&pdev->dev, "no irq resource?\n"); | ||
499 | return irq; | ||
500 | } | ||
501 | |||
502 | spin_lock_init(&qspi->lock); | ||
503 | mutex_init(&qspi->list_lock); | ||
504 | |||
505 | qspi->base = devm_ioremap_resource(&pdev->dev, r); | ||
506 | if (IS_ERR(qspi->base)) { | ||
507 | ret = PTR_ERR(qspi->base); | ||
508 | goto free_master; | ||
509 | } | ||
510 | |||
511 | ret = devm_request_threaded_irq(&pdev->dev, irq, ti_qspi_isr, | ||
512 | ti_qspi_threaded_isr, 0, | ||
513 | dev_name(&pdev->dev), qspi); | ||
514 | if (ret < 0) { | ||
515 | dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", | ||
516 | irq); | ||
517 | goto free_master; | ||
518 | } | ||
519 | |||
520 | qspi->fclk = devm_clk_get(&pdev->dev, "fck"); | ||
521 | if (IS_ERR(qspi->fclk)) { | ||
522 | ret = PTR_ERR(qspi->fclk); | ||
523 | dev_err(&pdev->dev, "could not get clk: %d\n", ret); | ||
524 | } | ||
525 | |||
526 | init_completion(&qspi->transfer_complete); | ||
527 | |||
528 | pm_runtime_use_autosuspend(&pdev->dev); | ||
529 | pm_runtime_set_autosuspend_delay(&pdev->dev, QSPI_AUTOSUSPEND_TIMEOUT); | ||
530 | pm_runtime_enable(&pdev->dev); | ||
531 | |||
532 | if (!of_property_read_u32(np, "spi-max-frequency", &max_freq)) | ||
533 | qspi->spi_max_frequency = max_freq; | ||
534 | |||
535 | ret = spi_register_master(master); | ||
536 | if (ret) | ||
537 | goto free_master; | ||
538 | |||
539 | return 0; | ||
540 | |||
541 | free_master: | ||
542 | spi_master_put(master); | ||
543 | return ret; | ||
544 | } | ||
545 | |||
546 | static int ti_qspi_remove(struct platform_device *pdev) | ||
547 | { | ||
548 | struct ti_qspi *qspi = platform_get_drvdata(pdev); | ||
549 | |||
550 | spi_unregister_master(qspi->master); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static const struct dev_pm_ops ti_qspi_pm_ops = { | ||
556 | .runtime_resume = ti_qspi_runtime_resume, | ||
557 | }; | ||
558 | |||
559 | static struct platform_driver ti_qspi_driver = { | ||
560 | .probe = ti_qspi_probe, | ||
561 | .remove = ti_qspi_remove, | ||
562 | .driver = { | ||
563 | .name = "ti,dra7xxx-qspi", | ||
564 | .owner = THIS_MODULE, | ||
565 | .pm = &ti_qspi_pm_ops, | ||
566 | .of_match_table = ti_qspi_match, | ||
567 | } | ||
568 | }; | ||
569 | |||
570 | module_platform_driver(ti_qspi_driver); | ||
571 | |||
572 | MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>"); | ||
573 | MODULE_LICENSE("GPL v2"); | ||
574 | MODULE_DESCRIPTION("TI QSPI controller driver"); | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 7ed5c147c073..6ef349f82b5f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -553,6 +553,10 @@ static void spi_pump_messages(struct kthread_work *work) | |||
553 | master->unprepare_transfer_hardware(master)) | 553 | master->unprepare_transfer_hardware(master)) |
554 | dev_err(&master->dev, | 554 | dev_err(&master->dev, |
555 | "failed to unprepare transfer hardware\n"); | 555 | "failed to unprepare transfer hardware\n"); |
556 | if (master->auto_runtime_pm) { | ||
557 | pm_runtime_mark_last_busy(master->dev.parent); | ||
558 | pm_runtime_put_autosuspend(master->dev.parent); | ||
559 | } | ||
556 | return; | 560 | return; |
557 | } | 561 | } |
558 | 562 | ||
@@ -572,11 +576,23 @@ static void spi_pump_messages(struct kthread_work *work) | |||
572 | master->busy = true; | 576 | master->busy = true; |
573 | spin_unlock_irqrestore(&master->queue_lock, flags); | 577 | spin_unlock_irqrestore(&master->queue_lock, flags); |
574 | 578 | ||
579 | if (!was_busy && master->auto_runtime_pm) { | ||
580 | ret = pm_runtime_get_sync(master->dev.parent); | ||
581 | if (ret < 0) { | ||
582 | dev_err(&master->dev, "Failed to power device: %d\n", | ||
583 | ret); | ||
584 | return; | ||
585 | } | ||
586 | } | ||
587 | |||
575 | if (!was_busy && master->prepare_transfer_hardware) { | 588 | if (!was_busy && master->prepare_transfer_hardware) { |
576 | ret = master->prepare_transfer_hardware(master); | 589 | ret = master->prepare_transfer_hardware(master); |
577 | if (ret) { | 590 | if (ret) { |
578 | dev_err(&master->dev, | 591 | dev_err(&master->dev, |
579 | "failed to prepare transfer hardware\n"); | 592 | "failed to prepare transfer hardware\n"); |
593 | |||
594 | if (master->auto_runtime_pm) | ||
595 | pm_runtime_put(master->dev.parent); | ||
580 | return; | 596 | return; |
581 | } | 597 | } |
582 | } | 598 | } |
@@ -869,6 +885,51 @@ static void of_register_spi_devices(struct spi_master *master) | |||
869 | if (of_find_property(nc, "spi-3wire", NULL)) | 885 | if (of_find_property(nc, "spi-3wire", NULL)) |
870 | spi->mode |= SPI_3WIRE; | 886 | spi->mode |= SPI_3WIRE; |
871 | 887 | ||
888 | /* Device DUAL/QUAD mode */ | ||
889 | prop = of_get_property(nc, "spi-tx-nbits", &len); | ||
890 | if (!prop || len < sizeof(*prop)) { | ||
891 | dev_err(&master->dev, "%s has no 'spi-tx-nbits' property\n", | ||
892 | nc->full_name); | ||
893 | spi_dev_put(spi); | ||
894 | continue; | ||
895 | } | ||
896 | switch (be32_to_cpup(prop)) { | ||
897 | case SPI_NBITS_SINGLE: | ||
898 | break; | ||
899 | case SPI_NBITS_DUAL: | ||
900 | spi->mode |= SPI_TX_DUAL; | ||
901 | break; | ||
902 | case SPI_NBITS_QUAD: | ||
903 | spi->mode |= SPI_TX_QUAD; | ||
904 | break; | ||
905 | default: | ||
906 | dev_err(&master->dev, "spi-tx-nbits value is not supported\n"); | ||
907 | spi_dev_put(spi); | ||
908 | continue; | ||
909 | } | ||
910 | |||
911 | prop = of_get_property(nc, "spi-rx-nbits", &len); | ||
912 | if (!prop || len < sizeof(*prop)) { | ||
913 | dev_err(&master->dev, "%s has no 'spi-rx-nbits' property\n", | ||
914 | nc->full_name); | ||
915 | spi_dev_put(spi); | ||
916 | continue; | ||
917 | } | ||
918 | switch (be32_to_cpup(prop)) { | ||
919 | case SPI_NBITS_SINGLE: | ||
920 | break; | ||
921 | case SPI_NBITS_DUAL: | ||
922 | spi->mode |= SPI_RX_DUAL; | ||
923 | break; | ||
924 | case SPI_NBITS_QUAD: | ||
925 | spi->mode |= SPI_RX_QUAD; | ||
926 | break; | ||
927 | default: | ||
928 | dev_err(&master->dev, "spi-rx-nbits value is not supported\n"); | ||
929 | spi_dev_put(spi); | ||
930 | continue; | ||
931 | } | ||
932 | |||
872 | /* Device speed */ | 933 | /* Device speed */ |
873 | prop = of_get_property(nc, "spi-max-frequency", &len); | 934 | prop = of_get_property(nc, "spi-max-frequency", &len); |
874 | if (!prop || len < sizeof(*prop)) { | 935 | if (!prop || len < sizeof(*prop)) { |
@@ -1316,6 +1377,19 @@ int spi_setup(struct spi_device *spi) | |||
1316 | unsigned bad_bits; | 1377 | unsigned bad_bits; |
1317 | int status = 0; | 1378 | int status = 0; |
1318 | 1379 | ||
1380 | /* check mode to prevent that DUAL and QUAD set at the same time | ||
1381 | */ | ||
1382 | if (((spi->mode & SPI_TX_DUAL) && (spi->mode & SPI_TX_QUAD)) || | ||
1383 | ((spi->mode & SPI_RX_DUAL) && (spi->mode & SPI_RX_QUAD))) { | ||
1384 | dev_err(&spi->dev, | ||
1385 | "setup: can not select dual and quad at the same time\n"); | ||
1386 | return -EINVAL; | ||
1387 | } | ||
1388 | /* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden | ||
1389 | */ | ||
1390 | if ((spi->mode & SPI_3WIRE) && (spi->mode & | ||
1391 | (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD))) | ||
1392 | return -EINVAL; | ||
1319 | /* help drivers fail *cleanly* when they need options | 1393 | /* help drivers fail *cleanly* when they need options |
1320 | * that aren't supported with their current master | 1394 | * that aren't supported with their current master |
1321 | */ | 1395 | */ |
@@ -1378,6 +1452,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) | |||
1378 | /** | 1452 | /** |
1379 | * Set transfer bits_per_word and max speed as spi device default if | 1453 | * Set transfer bits_per_word and max speed as spi device default if |
1380 | * it is not set for this transfer. | 1454 | * it is not set for this transfer. |
1455 | * Set transfer tx_nbits and rx_nbits as single transfer default | ||
1456 | * (SPI_NBITS_SINGLE) if it is not set for this transfer. | ||
1381 | */ | 1457 | */ |
1382 | list_for_each_entry(xfer, &message->transfers, transfer_list) { | 1458 | list_for_each_entry(xfer, &message->transfers, transfer_list) { |
1383 | message->frame_length += xfer->len; | 1459 | message->frame_length += xfer->len; |
@@ -1404,7 +1480,47 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) | |||
1404 | return -EINVAL; | 1480 | return -EINVAL; |
1405 | if (xfer->speed_hz && master->max_speed_hz && | 1481 | if (xfer->speed_hz && master->max_speed_hz && |
1406 | xfer->speed_hz > master->max_speed_hz) | 1482 | xfer->speed_hz > master->max_speed_hz) |
1407 | return -EINVAL; | 1483 | |
1484 | if (xfer->tx_buf && !xfer->tx_nbits) | ||
1485 | xfer->tx_nbits = SPI_NBITS_SINGLE; | ||
1486 | if (xfer->rx_buf && !xfer->rx_nbits) | ||
1487 | xfer->rx_nbits = SPI_NBITS_SINGLE; | ||
1488 | /* check transfer tx/rx_nbits: | ||
1489 | * 1. keep the value is not out of single, dual and quad | ||
1490 | * 2. keep tx/rx_nbits is contained by mode in spi_device | ||
1491 | * 3. if SPI_3WIRE, tx/rx_nbits should be in single | ||
1492 | */ | ||
1493 | if (xfer->tx_buf) { | ||
1494 | if (xfer->tx_nbits != SPI_NBITS_SINGLE && | ||
1495 | xfer->tx_nbits != SPI_NBITS_DUAL && | ||
1496 | xfer->tx_nbits != SPI_NBITS_QUAD) | ||
1497 | return -EINVAL; | ||
1498 | if ((xfer->tx_nbits == SPI_NBITS_DUAL) && | ||
1499 | !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) | ||
1500 | return -EINVAL; | ||
1501 | if ((xfer->tx_nbits == SPI_NBITS_QUAD) && | ||
1502 | !(spi->mode & SPI_TX_QUAD)) | ||
1503 | return -EINVAL; | ||
1504 | if ((spi->mode & SPI_3WIRE) && | ||
1505 | (xfer->tx_nbits != SPI_NBITS_SINGLE)) | ||
1506 | return -EINVAL; | ||
1507 | } | ||
1508 | /* check transfer rx_nbits */ | ||
1509 | if (xfer->rx_buf) { | ||
1510 | if (xfer->rx_nbits != SPI_NBITS_SINGLE && | ||
1511 | xfer->rx_nbits != SPI_NBITS_DUAL && | ||
1512 | xfer->rx_nbits != SPI_NBITS_QUAD) | ||
1513 | return -EINVAL; | ||
1514 | if ((xfer->rx_nbits == SPI_NBITS_DUAL) && | ||
1515 | !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) | ||
1516 | return -EINVAL; | ||
1517 | if ((xfer->rx_nbits == SPI_NBITS_QUAD) && | ||
1518 | !(spi->mode & SPI_RX_QUAD)) | ||
1519 | return -EINVAL; | ||
1520 | if ((spi->mode & SPI_3WIRE) && | ||
1521 | (xfer->rx_nbits != SPI_NBITS_SINGLE)) | ||
1522 | return -EINVAL; | ||
1523 | } | ||
1408 | } | 1524 | } |
1409 | 1525 | ||
1410 | message->spi = spi; | 1526 | message->spi = spi; |