diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-28 21:04:06 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-28 21:04:06 -0400 |
| commit | 2f19e7a7e63a04f4bbaf327d9d0e69ac800b2b8f (patch) | |
| tree | 5e395102e3e0164a3347d9cfd7696505677618ad | |
| parent | 8f0566118e2def0bb8e05de8b19942e9e8111c9a (diff) | |
| parent | c949a8e8b43f2c75567269bcc9a50d704ae3c420 (diff) | |
Merge tag 'spi-fix-v4.19-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Mark writes:
"spi: Fixes for v4.19
Quite a few fixes for the Renesas drivers in here, plus a fix for the
Tegra driver and some documentation fixes for the recently added
spi-mem code. The Tegra fix is relatively large but fairly
straightforward and mechanical, it runs on probe so it's been
reasonably well covered in -next testing."
* tag 'spi-fix-v4.19-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: spi-mem: Move the DMA-able constraint doc to the kerneldoc header
spi: spi-mem: Add missing description for data.nbytes field
spi: rspi: Fix interrupted DMA transfers
spi: rspi: Fix invalid SPI use during system suspend
spi: sh-msiof: Fix handling of write value for SISTR register
spi: sh-msiof: Fix invalid SPI use during system suspend
spi: gpio: Fix copy-and-paste error
spi: tegra20-slink: explicitly enable/disable clock
| -rw-r--r-- | drivers/spi/spi-gpio.c | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-rspi.c | 34 | ||||
| -rw-r--r-- | drivers/spi/spi-sh-msiof.c | 28 | ||||
| -rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 31 | ||||
| -rw-r--r-- | include/linux/spi/spi-mem.h | 7 |
5 files changed, 86 insertions, 18 deletions
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0626e6e3ea0c..421bfc7dda67 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
| @@ -300,8 +300,8 @@ static int spi_gpio_request(struct device *dev, | |||
| 300 | *mflags |= SPI_MASTER_NO_RX; | 300 | *mflags |= SPI_MASTER_NO_RX; |
| 301 | 301 | ||
| 302 | spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); | 302 | spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); |
| 303 | if (IS_ERR(spi_gpio->mosi)) | 303 | if (IS_ERR(spi_gpio->sck)) |
| 304 | return PTR_ERR(spi_gpio->mosi); | 304 | return PTR_ERR(spi_gpio->sck); |
| 305 | 305 | ||
| 306 | for (i = 0; i < num_chipselects; i++) { | 306 | for (i = 0; i < num_chipselects; i++) { |
| 307 | spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", | 307 | spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", |
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 95dc4d78618d..b37de1d991d6 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -598,11 +598,13 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx, | |||
| 598 | 598 | ||
| 599 | ret = wait_event_interruptible_timeout(rspi->wait, | 599 | ret = wait_event_interruptible_timeout(rspi->wait, |
| 600 | rspi->dma_callbacked, HZ); | 600 | rspi->dma_callbacked, HZ); |
| 601 | if (ret > 0 && rspi->dma_callbacked) | 601 | if (ret > 0 && rspi->dma_callbacked) { |
| 602 | ret = 0; | 602 | ret = 0; |
| 603 | else if (!ret) { | 603 | } else { |
| 604 | dev_err(&rspi->master->dev, "DMA timeout\n"); | 604 | if (!ret) { |
| 605 | ret = -ETIMEDOUT; | 605 | dev_err(&rspi->master->dev, "DMA timeout\n"); |
| 606 | ret = -ETIMEDOUT; | ||
| 607 | } | ||
| 606 | if (tx) | 608 | if (tx) |
| 607 | dmaengine_terminate_all(rspi->master->dma_tx); | 609 | dmaengine_terminate_all(rspi->master->dma_tx); |
| 608 | if (rx) | 610 | if (rx) |
| @@ -1350,12 +1352,36 @@ static const struct platform_device_id spi_driver_ids[] = { | |||
| 1350 | 1352 | ||
| 1351 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); | 1353 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); |
| 1352 | 1354 | ||
| 1355 | #ifdef CONFIG_PM_SLEEP | ||
| 1356 | static int rspi_suspend(struct device *dev) | ||
| 1357 | { | ||
| 1358 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1359 | struct rspi_data *rspi = platform_get_drvdata(pdev); | ||
| 1360 | |||
| 1361 | return spi_master_suspend(rspi->master); | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | static int rspi_resume(struct device *dev) | ||
| 1365 | { | ||
| 1366 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1367 | struct rspi_data *rspi = platform_get_drvdata(pdev); | ||
| 1368 | |||
| 1369 | return spi_master_resume(rspi->master); | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | static SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume); | ||
| 1373 | #define DEV_PM_OPS &rspi_pm_ops | ||
| 1374 | #else | ||
| 1375 | #define DEV_PM_OPS NULL | ||
| 1376 | #endif /* CONFIG_PM_SLEEP */ | ||
| 1377 | |||
| 1353 | static struct platform_driver rspi_driver = { | 1378 | static struct platform_driver rspi_driver = { |
| 1354 | .probe = rspi_probe, | 1379 | .probe = rspi_probe, |
| 1355 | .remove = rspi_remove, | 1380 | .remove = rspi_remove, |
| 1356 | .id_table = spi_driver_ids, | 1381 | .id_table = spi_driver_ids, |
| 1357 | .driver = { | 1382 | .driver = { |
| 1358 | .name = "renesas_spi", | 1383 | .name = "renesas_spi", |
| 1384 | .pm = DEV_PM_OPS, | ||
| 1359 | .of_match_table = of_match_ptr(rspi_of_match), | 1385 | .of_match_table = of_match_ptr(rspi_of_match), |
| 1360 | }, | 1386 | }, |
| 1361 | }; | 1387 | }; |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 539d6d1a277a..101cd6aae2ea 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -397,7 +397,8 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p, | |||
| 397 | 397 | ||
| 398 | static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p) | 398 | static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p) |
| 399 | { | 399 | { |
| 400 | sh_msiof_write(p, STR, sh_msiof_read(p, STR)); | 400 | sh_msiof_write(p, STR, |
| 401 | sh_msiof_read(p, STR) & ~(STR_TDREQ | STR_RDREQ)); | ||
| 401 | } | 402 | } |
| 402 | 403 | ||
| 403 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, | 404 | static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p, |
| @@ -1426,12 +1427,37 @@ static const struct platform_device_id spi_driver_ids[] = { | |||
| 1426 | }; | 1427 | }; |
| 1427 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); | 1428 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); |
| 1428 | 1429 | ||
| 1430 | #ifdef CONFIG_PM_SLEEP | ||
| 1431 | static int sh_msiof_spi_suspend(struct device *dev) | ||
| 1432 | { | ||
| 1433 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1434 | struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev); | ||
| 1435 | |||
| 1436 | return spi_master_suspend(p->master); | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | static int sh_msiof_spi_resume(struct device *dev) | ||
| 1440 | { | ||
| 1441 | struct platform_device *pdev = to_platform_device(dev); | ||
| 1442 | struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev); | ||
| 1443 | |||
| 1444 | return spi_master_resume(p->master); | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend, | ||
| 1448 | sh_msiof_spi_resume); | ||
| 1449 | #define DEV_PM_OPS &sh_msiof_spi_pm_ops | ||
| 1450 | #else | ||
| 1451 | #define DEV_PM_OPS NULL | ||
| 1452 | #endif /* CONFIG_PM_SLEEP */ | ||
| 1453 | |||
| 1429 | static struct platform_driver sh_msiof_spi_drv = { | 1454 | static struct platform_driver sh_msiof_spi_drv = { |
| 1430 | .probe = sh_msiof_spi_probe, | 1455 | .probe = sh_msiof_spi_probe, |
| 1431 | .remove = sh_msiof_spi_remove, | 1456 | .remove = sh_msiof_spi_remove, |
| 1432 | .id_table = spi_driver_ids, | 1457 | .id_table = spi_driver_ids, |
| 1433 | .driver = { | 1458 | .driver = { |
| 1434 | .name = "spi_sh_msiof", | 1459 | .name = "spi_sh_msiof", |
| 1460 | .pm = DEV_PM_OPS, | ||
| 1435 | .of_match_table = of_match_ptr(sh_msiof_match), | 1461 | .of_match_table = of_match_ptr(sh_msiof_match), |
| 1436 | }, | 1462 | }, |
| 1437 | }; | 1463 | }; |
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 6f7b946b5ced..1427f343b39a 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c | |||
| @@ -1063,6 +1063,24 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
| 1063 | goto exit_free_master; | 1063 | goto exit_free_master; |
| 1064 | } | 1064 | } |
| 1065 | 1065 | ||
| 1066 | /* disabled clock may cause interrupt storm upon request */ | ||
| 1067 | tspi->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1068 | if (IS_ERR(tspi->clk)) { | ||
| 1069 | ret = PTR_ERR(tspi->clk); | ||
| 1070 | dev_err(&pdev->dev, "Can not get clock %d\n", ret); | ||
| 1071 | goto exit_free_master; | ||
| 1072 | } | ||
| 1073 | ret = clk_prepare(tspi->clk); | ||
| 1074 | if (ret < 0) { | ||
| 1075 | dev_err(&pdev->dev, "Clock prepare failed %d\n", ret); | ||
| 1076 | goto exit_free_master; | ||
| 1077 | } | ||
| 1078 | ret = clk_enable(tspi->clk); | ||
| 1079 | if (ret < 0) { | ||
| 1080 | dev_err(&pdev->dev, "Clock enable failed %d\n", ret); | ||
| 1081 | goto exit_free_master; | ||
| 1082 | } | ||
| 1083 | |||
| 1066 | spi_irq = platform_get_irq(pdev, 0); | 1084 | spi_irq = platform_get_irq(pdev, 0); |
| 1067 | tspi->irq = spi_irq; | 1085 | tspi->irq = spi_irq; |
| 1068 | ret = request_threaded_irq(tspi->irq, tegra_slink_isr, | 1086 | ret = request_threaded_irq(tspi->irq, tegra_slink_isr, |
| @@ -1071,14 +1089,7 @@ static int tegra_slink_probe(struct platform_device *pdev) | |||
| 1071 | if (ret < 0) { | 1089 | if (ret < 0) { |
| 1072 | dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", | 1090 | dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", |
| 1073 | tspi->irq); | 1091 | tspi->irq); |
| 1074 | goto exit_free_master; | 1092 | goto exit_clk_disable; |
| 1075 | } | ||
| 1076 | |||
| 1077 | tspi->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 1078 | if (IS_ERR(tspi->clk)) { | ||
| 1079 | dev_err(&pdev->dev, "can not get clock\n"); | ||
| 1080 | ret = PTR_ERR(tspi->clk); | ||
| 1081 | goto exit_free_irq; | ||
| 1082 | } | 1093 | } |
| 1083 | 1094 | ||
| 1084 | tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); | 1095 | tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi"); |
| @@ -1138,6 +1149,8 @@ exit_rx_dma_free: | |||
| 1138 | tegra_slink_deinit_dma_param(tspi, true); | 1149 | tegra_slink_deinit_dma_param(tspi, true); |
| 1139 | exit_free_irq: | 1150 | exit_free_irq: |
| 1140 | free_irq(spi_irq, tspi); | 1151 | free_irq(spi_irq, tspi); |
| 1152 | exit_clk_disable: | ||
| 1153 | clk_disable(tspi->clk); | ||
| 1141 | exit_free_master: | 1154 | exit_free_master: |
| 1142 | spi_master_put(master); | 1155 | spi_master_put(master); |
| 1143 | return ret; | 1156 | return ret; |
| @@ -1150,6 +1163,8 @@ static int tegra_slink_remove(struct platform_device *pdev) | |||
| 1150 | 1163 | ||
| 1151 | free_irq(tspi->irq, tspi); | 1164 | free_irq(tspi->irq, tspi); |
| 1152 | 1165 | ||
| 1166 | clk_disable(tspi->clk); | ||
| 1167 | |||
| 1153 | if (tspi->tx_dma_chan) | 1168 | if (tspi->tx_dma_chan) |
| 1154 | tegra_slink_deinit_dma_param(tspi, false); | 1169 | tegra_slink_deinit_dma_param(tspi, false); |
| 1155 | 1170 | ||
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index b2bd4b4127c4..69ee30456864 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h | |||
| @@ -81,8 +81,10 @@ enum spi_mem_data_dir { | |||
| 81 | * @dummy.buswidth: number of IO lanes used to transmit the dummy bytes | 81 | * @dummy.buswidth: number of IO lanes used to transmit the dummy bytes |
| 82 | * @data.buswidth: number of IO lanes used to send/receive the data | 82 | * @data.buswidth: number of IO lanes used to send/receive the data |
| 83 | * @data.dir: direction of the transfer | 83 | * @data.dir: direction of the transfer |
| 84 | * @data.buf.in: input buffer | 84 | * @data.nbytes: number of data bytes to send/receive. Can be zero if the |
| 85 | * @data.buf.out: output buffer | 85 | * operation does not involve transferring data |
| 86 | * @data.buf.in: input buffer (must be DMA-able) | ||
| 87 | * @data.buf.out: output buffer (must be DMA-able) | ||
| 86 | */ | 88 | */ |
| 87 | struct spi_mem_op { | 89 | struct spi_mem_op { |
| 88 | struct { | 90 | struct { |
| @@ -105,7 +107,6 @@ struct spi_mem_op { | |||
| 105 | u8 buswidth; | 107 | u8 buswidth; |
| 106 | enum spi_mem_data_dir dir; | 108 | enum spi_mem_data_dir dir; |
| 107 | unsigned int nbytes; | 109 | unsigned int nbytes; |
| 108 | /* buf.{in,out} must be DMA-able. */ | ||
| 109 | union { | 110 | union { |
| 110 | void *in; | 111 | void *in; |
| 111 | const void *out; | 112 | const void *out; |
