summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2018-09-05 11:49:39 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-13 10:09:27 +0300
commit6ea058b70a290b02f1d8a15f6503928cc21a85e1 (patch)
treeb3c4e841fb32a156be2fb2d1fb85d844a12b4505 /drivers/spi
parent5a5b2a2bd334aedf3aa8520fc3b37484a72be5d5 (diff)
downloadlinux-6ea058b70a290b02f1d8a15f6503928cc21a85e1.tar.xz
spi: rspi: Fix interrupted DMA transfers
commit 8dbbaa47b96f6ea5f09f922b4effff3c505cd8cf upstream. 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 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-rspi.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 54bb0faec155..4ee0bfa86e4a 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -538,11 +538,13 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,
ret = wait_event_interruptible_timeout(rspi->wait,
rspi->dma_callbacked, HZ);
- if (ret > 0 && rspi->dma_callbacked)
+ if (ret > 0 && rspi->dma_callbacked) {
ret = 0;
- else if (!ret) {
- dev_err(&rspi->master->dev, "DMA timeout\n");
- ret = -ETIMEDOUT;
+ } else {
+ if (!ret) {
+ dev_err(&rspi->master->dev, "DMA timeout\n");
+ ret = -ETIMEDOUT;
+ }
if (tx)
dmaengine_terminate_all(rspi->master->dma_tx);
if (rx)