diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2018-09-05 04:49:39 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-09-05 07:40:12 -0400 |
commit | 8dbbaa47b96f6ea5f09f922b4effff3c505cd8cf (patch) | |
tree | 2e1c6b91960545173facbe9cf499fef71cc2f364 | |
parent | c1ca59c22c56930b377a665fdd1b43351887830b (diff) |
spi: rspi: Fix interrupted DMA transfers
When interrupted, wait_event_interruptible_timeout() returns
-ERESTARTSYS, and the SPI transfer in progress will fail, as expected:
m25p80 spi0.0: SPI transfer failed: -512
spi_master spi0: failed to transfer one message from queue
However, as the underlying DMA transfers may not have completed, all
subsequent SPI transfers may start to fail:
spi_master spi0: receive timeout
qspi_transfer_out_in() returned -110
m25p80 spi0.0: SPI transfer failed: -110
spi_master spi0: failed to transfer one message from queue
Fix this by calling dmaengine_terminate_all() not only for timeouts, but
also for errors.
This can be reproduced on r8a7991/koelsch, using "hd /dev/mtd0" followed
by CTRL-C.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/spi/spi-rspi.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index f93a4587e3fb..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) |