diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-05 16:41:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-05 16:41:37 -0400 |
commit | 5003bc6cc60ef700692da9bf4d3953aa0770d300 (patch) | |
tree | 37da12e6c66c6d724b4fc7ce62f0ddfdaa7f9036 | |
parent | 1b5caa3eaa5f98a0d29ac46c7b545091520c5b26 (diff) | |
parent | cb39f732abbe4f38d2bef8e0a1c8bd5c242fc1b7 (diff) |
Merge tag 'spi-fix-v4.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi fixes from Mark Brown:
"A couple of driver specific fixes here that came in since the merge
window plus one core fix for locking in cases where a client driver
grabs a lock on the whole bus for an extended series of operations
that was introduced by the changes to support accelerated flash
operations"
* tag 'spi-fix-v4.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: rockchip: fix probe deferral handling
spi: omap2-mcspi: fix dma transfer for vmalloced buffer
spi: fix possible deadlock between internal bus locks and bus_lock_flag
spi: imx: Fix possible NULL pointer deref
spi: imx: only do necessary changes to ECSPIx_CONFIGREG
spi: rockchip: Spelling s/divsor/divisor/
-rw-r--r-- | drivers/spi/spi-imx.c | 16 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 62 | ||||
-rw-r--r-- | drivers/spi/spi-rockchip.c | 16 | ||||
-rw-r--r-- | drivers/spi/spi.c | 4 |
4 files changed, 43 insertions, 55 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e7a19be87c38..50769078e72e 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -211,11 +211,15 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, | |||
211 | struct spi_transfer *transfer) | 211 | struct spi_transfer *transfer) |
212 | { | 212 | { |
213 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); | 213 | struct spi_imx_data *spi_imx = spi_master_get_devdata(master); |
214 | unsigned int bpw = transfer->bits_per_word; | 214 | unsigned int bpw; |
215 | 215 | ||
216 | if (!master->dma_rx) | 216 | if (!master->dma_rx) |
217 | return false; | 217 | return false; |
218 | 218 | ||
219 | if (!transfer) | ||
220 | return false; | ||
221 | |||
222 | bpw = transfer->bits_per_word; | ||
219 | if (!bpw) | 223 | if (!bpw) |
220 | bpw = spi->bits_per_word; | 224 | bpw = spi->bits_per_word; |
221 | 225 | ||
@@ -333,8 +337,9 @@ static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) | |||
333 | static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | 337 | static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, |
334 | struct spi_imx_config *config) | 338 | struct spi_imx_config *config) |
335 | { | 339 | { |
336 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0; | 340 | u32 ctrl = MX51_ECSPI_CTRL_ENABLE; |
337 | u32 clk = config->speed_hz, delay, reg; | 341 | u32 clk = config->speed_hz, delay, reg; |
342 | u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); | ||
338 | 343 | ||
339 | /* | 344 | /* |
340 | * The hardware seems to have a race condition when changing modes. The | 345 | * The hardware seems to have a race condition when changing modes. The |
@@ -358,13 +363,20 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, | |||
358 | 363 | ||
359 | if (config->mode & SPI_CPHA) | 364 | if (config->mode & SPI_CPHA) |
360 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); | 365 | cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); |
366 | else | ||
367 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPHA(config->cs); | ||
361 | 368 | ||
362 | if (config->mode & SPI_CPOL) { | 369 | if (config->mode & SPI_CPOL) { |
363 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); | 370 | cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); |
364 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); | 371 | cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); |
372 | } else { | ||
373 | cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(config->cs); | ||
374 | cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(config->cs); | ||
365 | } | 375 | } |
366 | if (config->mode & SPI_CS_HIGH) | 376 | if (config->mode & SPI_CS_HIGH) |
367 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); | 377 | cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); |
378 | else | ||
379 | cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs); | ||
368 | 380 | ||
369 | if (spi_imx->usedma) | 381 | if (spi_imx->usedma) |
370 | ctrl |= MX51_ECSPI_CTRL_SMC; | 382 | ctrl |= MX51_ECSPI_CTRL_SMC; |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 0caa3c8bef46..43a02e377b3b 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -423,16 +423,12 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
423 | 423 | ||
424 | if (mcspi_dma->dma_tx) { | 424 | if (mcspi_dma->dma_tx) { |
425 | struct dma_async_tx_descriptor *tx; | 425 | struct dma_async_tx_descriptor *tx; |
426 | struct scatterlist sg; | ||
427 | 426 | ||
428 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); | 427 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); |
429 | 428 | ||
430 | sg_init_table(&sg, 1); | 429 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl, |
431 | sg_dma_address(&sg) = xfer->tx_dma; | 430 | xfer->tx_sg.nents, DMA_MEM_TO_DEV, |
432 | sg_dma_len(&sg) = xfer->len; | 431 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
433 | |||
434 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, | ||
435 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
436 | if (tx) { | 432 | if (tx) { |
437 | tx->callback = omap2_mcspi_tx_callback; | 433 | tx->callback = omap2_mcspi_tx_callback; |
438 | tx->callback_param = spi; | 434 | tx->callback_param = spi; |
@@ -478,20 +474,15 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
478 | 474 | ||
479 | if (mcspi_dma->dma_rx) { | 475 | if (mcspi_dma->dma_rx) { |
480 | struct dma_async_tx_descriptor *tx; | 476 | struct dma_async_tx_descriptor *tx; |
481 | struct scatterlist sg; | ||
482 | 477 | ||
483 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); | 478 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); |
484 | 479 | ||
485 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) | 480 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) |
486 | dma_count -= es; | 481 | dma_count -= es; |
487 | 482 | ||
488 | sg_init_table(&sg, 1); | 483 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl, |
489 | sg_dma_address(&sg) = xfer->rx_dma; | 484 | xfer->rx_sg.nents, DMA_DEV_TO_MEM, |
490 | sg_dma_len(&sg) = dma_count; | 485 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
491 | |||
492 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | ||
493 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | | ||
494 | DMA_CTRL_ACK); | ||
495 | if (tx) { | 486 | if (tx) { |
496 | tx->callback = omap2_mcspi_rx_callback; | 487 | tx->callback = omap2_mcspi_rx_callback; |
497 | tx->callback_param = spi; | 488 | tx->callback_param = spi; |
@@ -505,8 +496,6 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
505 | omap2_mcspi_set_dma_req(spi, 1, 1); | 496 | omap2_mcspi_set_dma_req(spi, 1, 1); |
506 | 497 | ||
507 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 498 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
508 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | ||
509 | DMA_FROM_DEVICE); | ||
510 | 499 | ||
511 | if (mcspi->fifo_depth > 0) | 500 | if (mcspi->fifo_depth > 0) |
512 | return count; | 501 | return count; |
@@ -619,8 +608,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
619 | 608 | ||
620 | if (tx != NULL) { | 609 | if (tx != NULL) { |
621 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 610 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
622 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, | ||
623 | DMA_TO_DEVICE); | ||
624 | 611 | ||
625 | if (mcspi->fifo_depth > 0) { | 612 | if (mcspi->fifo_depth > 0) { |
626 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; | 613 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; |
@@ -1087,6 +1074,16 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
1087 | gpio_free(spi->cs_gpio); | 1074 | gpio_free(spi->cs_gpio); |
1088 | } | 1075 | } |
1089 | 1076 | ||
1077 | static bool omap2_mcspi_can_dma(struct spi_master *master, | ||
1078 | struct spi_device *spi, | ||
1079 | struct spi_transfer *xfer) | ||
1080 | { | ||
1081 | if (xfer->len < DMA_MIN_BYTES) | ||
1082 | return false; | ||
1083 | |||
1084 | return true; | ||
1085 | } | ||
1086 | |||
1090 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, | 1087 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, |
1091 | struct spi_device *spi, struct spi_transfer *t) | 1088 | struct spi_device *spi, struct spi_transfer *t) |
1092 | { | 1089 | { |
@@ -1268,32 +1265,6 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, | |||
1268 | return -EINVAL; | 1265 | return -EINVAL; |
1269 | } | 1266 | } |
1270 | 1267 | ||
1271 | if (len < DMA_MIN_BYTES) | ||
1272 | goto skip_dma_map; | ||
1273 | |||
1274 | if (mcspi_dma->dma_tx && tx_buf != NULL) { | ||
1275 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | ||
1276 | len, DMA_TO_DEVICE); | ||
1277 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | ||
1278 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1279 | 'T', len); | ||
1280 | return -EINVAL; | ||
1281 | } | ||
1282 | } | ||
1283 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | ||
1284 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, | ||
1285 | DMA_FROM_DEVICE); | ||
1286 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { | ||
1287 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1288 | 'R', len); | ||
1289 | if (tx_buf != NULL) | ||
1290 | dma_unmap_single(mcspi->dev, t->tx_dma, | ||
1291 | len, DMA_TO_DEVICE); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | skip_dma_map: | ||
1297 | return omap2_mcspi_work_one(mcspi, spi, t); | 1268 | return omap2_mcspi_work_one(mcspi, spi, t); |
1298 | } | 1269 | } |
1299 | 1270 | ||
@@ -1377,6 +1348,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
1377 | master->transfer_one = omap2_mcspi_transfer_one; | 1348 | master->transfer_one = omap2_mcspi_transfer_one; |
1378 | master->set_cs = omap2_mcspi_set_cs; | 1349 | master->set_cs = omap2_mcspi_set_cs; |
1379 | master->cleanup = omap2_mcspi_cleanup; | 1350 | master->cleanup = omap2_mcspi_cleanup; |
1351 | master->can_dma = omap2_mcspi_can_dma; | ||
1380 | master->dev.of_node = node; | 1352 | master->dev.of_node = node; |
1381 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; | 1353 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; |
1382 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; | 1354 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; |
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index 8f50a4020f6f..6c6c0013ec7a 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c | |||
@@ -534,7 +534,7 @@ static void rockchip_spi_config(struct rockchip_spi *rs) | |||
534 | if (WARN_ON(rs->speed > MAX_SCLK_OUT)) | 534 | if (WARN_ON(rs->speed > MAX_SCLK_OUT)) |
535 | rs->speed = MAX_SCLK_OUT; | 535 | rs->speed = MAX_SCLK_OUT; |
536 | 536 | ||
537 | /* the minimum divsor is 2 */ | 537 | /* the minimum divisor is 2 */ |
538 | if (rs->max_freq < 2 * rs->speed) { | 538 | if (rs->max_freq < 2 * rs->speed) { |
539 | clk_set_rate(rs->spiclk, 2 * rs->speed); | 539 | clk_set_rate(rs->spiclk, 2 * rs->speed); |
540 | rs->max_freq = clk_get_rate(rs->spiclk); | 540 | rs->max_freq = clk_get_rate(rs->spiclk); |
@@ -730,23 +730,27 @@ static int rockchip_spi_probe(struct platform_device *pdev) | |||
730 | master->transfer_one = rockchip_spi_transfer_one; | 730 | master->transfer_one = rockchip_spi_transfer_one; |
731 | master->handle_err = rockchip_spi_handle_err; | 731 | master->handle_err = rockchip_spi_handle_err; |
732 | 732 | ||
733 | rs->dma_tx.ch = dma_request_slave_channel(rs->dev, "tx"); | 733 | rs->dma_tx.ch = dma_request_chan(rs->dev, "tx"); |
734 | if (IS_ERR_OR_NULL(rs->dma_tx.ch)) { | 734 | if (IS_ERR(rs->dma_tx.ch)) { |
735 | /* Check tx to see if we need defer probing driver */ | 735 | /* Check tx to see if we need defer probing driver */ |
736 | if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) { | 736 | if (PTR_ERR(rs->dma_tx.ch) == -EPROBE_DEFER) { |
737 | ret = -EPROBE_DEFER; | 737 | ret = -EPROBE_DEFER; |
738 | goto err_get_fifo_len; | 738 | goto err_get_fifo_len; |
739 | } | 739 | } |
740 | dev_warn(rs->dev, "Failed to request TX DMA channel\n"); | 740 | dev_warn(rs->dev, "Failed to request TX DMA channel\n"); |
741 | rs->dma_tx.ch = NULL; | ||
741 | } | 742 | } |
742 | 743 | ||
743 | rs->dma_rx.ch = dma_request_slave_channel(rs->dev, "rx"); | 744 | rs->dma_rx.ch = dma_request_chan(rs->dev, "rx"); |
744 | if (!rs->dma_rx.ch) { | 745 | if (IS_ERR(rs->dma_rx.ch)) { |
745 | if (rs->dma_tx.ch) { | 746 | if (PTR_ERR(rs->dma_rx.ch) == -EPROBE_DEFER) { |
746 | dma_release_channel(rs->dma_tx.ch); | 747 | dma_release_channel(rs->dma_tx.ch); |
747 | rs->dma_tx.ch = NULL; | 748 | rs->dma_tx.ch = NULL; |
749 | ret = -EPROBE_DEFER; | ||
750 | goto err_get_fifo_len; | ||
748 | } | 751 | } |
749 | dev_warn(rs->dev, "Failed to request RX DMA channel\n"); | 752 | dev_warn(rs->dev, "Failed to request RX DMA channel\n"); |
753 | rs->dma_rx.ch = NULL; | ||
750 | } | 754 | } |
751 | 755 | ||
752 | if (rs->dma_tx.ch && rs->dma_rx.ch) { | 756 | if (rs->dma_tx.ch && rs->dma_rx.ch) { |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index de2f2f90d799..0239b45eed92 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -1209,7 +1209,7 @@ static void spi_pump_messages(struct kthread_work *work) | |||
1209 | struct spi_master *master = | 1209 | struct spi_master *master = |
1210 | container_of(work, struct spi_master, pump_messages); | 1210 | container_of(work, struct spi_master, pump_messages); |
1211 | 1211 | ||
1212 | __spi_pump_messages(master, true, false); | 1212 | __spi_pump_messages(master, true, master->bus_lock_flag); |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static int spi_init_queue(struct spi_master *master) | 1215 | static int spi_init_queue(struct spi_master *master) |
@@ -2853,7 +2853,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message, | |||
2853 | */ | 2853 | */ |
2854 | int spi_sync(struct spi_device *spi, struct spi_message *message) | 2854 | int spi_sync(struct spi_device *spi, struct spi_message *message) |
2855 | { | 2855 | { |
2856 | return __spi_sync(spi, message, 0); | 2856 | return __spi_sync(spi, message, spi->master->bus_lock_flag); |
2857 | } | 2857 | } |
2858 | EXPORT_SYMBOL_GPL(spi_sync); | 2858 | EXPORT_SYMBOL_GPL(spi_sync); |
2859 | 2859 | ||