lkml.org 
[lkml]   [2018]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 205/328] spi: rspi: Fix interrupted DMA transfers
    3.16.62-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Geert Uytterhoeven <geert+renesas@glider.be>

    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>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/spi/spi-rspi.c | 10 ++++++----
    1 file changed, 6 insertions(+), 4 deletions(-)

    --- a/drivers/spi/spi-rspi.c
    +++ b/drivers/spi/spi-rspi.c
    @@ -538,11 +538,13 @@ static int rspi_dma_transfer(struct rspi

    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)
    \
     
     \ /
      Last update: 2018-12-09 23:18    [W:4.053 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site