diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2015-03-06 14:42:01 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-13 14:03:55 +0200 |
commit | 68cbdc1ae6dc23f7ee1ffdc59e30a34ccae56997 (patch) | |
tree | c59060f920532a85294647e92d1ad33a43344aa9 /drivers | |
parent | 2d57a8c4b8ca69d46a7244a9581334542f98bc33 (diff) |
spi: dw-mid: clear BUSY flag fist and test other one
commit 854d2f241d71f6ca08ccde30e6c7c2e403363e52 upstream.
The logic of DMA completion is broken now since test_and_clear_bit() never
returns the other bit is set. It means condition are always false and we have
spi_finalize_current_transfer() called per each DMA completion which is wrong.
The patch fixes logic by clearing BUSY bit first and then check for the other
one.
Fixes: 30c8eb52cc4a (spi: dw-mid: split rx and tx callbacks when DMA)
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/spi-dw-mid.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 22ca08a18b9e..8076e89f1ea1 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c @@ -108,7 +108,8 @@ static void dw_spi_dma_tx_done(void *arg) { struct dw_spi *dws = arg; - if (test_and_clear_bit(TX_BUSY, &dws->dma_chan_busy) & BIT(RX_BUSY)) + clear_bit(TX_BUSY, &dws->dma_chan_busy); + if (test_bit(RX_BUSY, &dws->dma_chan_busy)) return; dw_spi_xfer_done(dws); } @@ -156,7 +157,8 @@ static void dw_spi_dma_rx_done(void *arg) { struct dw_spi *dws = arg; - if (test_and_clear_bit(RX_BUSY, &dws->dma_chan_busy) & BIT(TX_BUSY)) + clear_bit(RX_BUSY, &dws->dma_chan_busy); + if (test_bit(TX_BUSY, &dws->dma_chan_busy)) return; dw_spi_xfer_done(dws); } |