| From | Greg Kroah-Hartman <> | Subject | [PATCH 3.19 65/75] spi: dw-mid: clear BUSY flag fist and test other one | Date | Fri, 10 Apr 2015 15:19:31 +0200 |
| |
3.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
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>
--- drivers/spi/spi-dw-mid.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- 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); }
|