diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2015-03-06 13:42:01 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-07 12:22:02 +0100 |
commit | 854d2f241d71f6ca08ccde30e6c7c2e403363e52 (patch) | |
tree | 28b2c40697eb3e3e316021541793ed646d177f69 /drivers/spi | |
parent | spi: dw-mid: avoid potential NULL dereference (diff) | |
download | linux-854d2f241d71f6ca08ccde30e6c7c2e403363e52.tar.xz linux-854d2f241d71f6ca08ccde30e6c7c2e403363e52.zip |
spi: dw-mid: clear BUSY flag fist and test other one
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>
Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/spi')
-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 3ce39d10fafb..4f8c798e0633 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); } |