diff mbox

[v2,resend,for,stable,1/1] spi: dw-mid: clear BUSY flag fist and test other one

Message ID 1425645721-18142-1-git-send-email-andriy.shevchenko@linux.intel.com (mailing list archive)
State Accepted
Commit 854d2f241d71f6ca08ccde30e6c7c2e403363e52
Headers show

Commit Message

Andy Shevchenko March 6, 2015, 12:42 p.m. UTC
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>
---
 drivers/spi/spi-dw-mid.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Mark Brown March 7, 2015, 11:22 a.m. UTC | #1
On Fri, Mar 06, 2015 at 02:42:01PM +0200, Andy Shevchenko wrote:
> 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.

Applied, thanks.  I assume you're also going to resend the other bits if
they're still valid?
Andy Shevchenko March 7, 2015, 7:14 p.m. UTC | #2
On Sat, Mar 7, 2015 at 1:22 PM, Mark Brown <broonie@kernel.org> wrote:
> On Fri, Mar 06, 2015 at 02:42:01PM +0200, Andy Shevchenko wrote:
>> 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.
>
> Applied, thanks.  I assume you're also going to resend the other bits if
> they're still valid?

Yes, they are.
I will do next working day (On Monday I think ).
diff mbox

Patch

diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index 3ce39d1..4f8c798 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);
 }