diff mbox

[v2,2/9] spi: dw-mid: clear BUSY flag fist and test other one

Message ID 1425320166-13788-3-git-send-email-andriy.shevchenko@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andy Shevchenko March 2, 2015, 6:15 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 6, 2015, 11:25 a.m. UTC | #1
On Mon, Mar 02, 2015 at 08:15:59PM +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.
> 
> 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)

The commit this is fixing is in v3.19 so this should go to stable but I
can't apply this against my fix/dw branch.  Can you generate a version
that can be applied there please?  We'll need to work out the merge
issues with the current code I gues...
Andy Shevchenko March 6, 2015, 12:40 p.m. UTC | #2
On Fri, 2015-03-06 at 11:25 +0000, Mark Brown wrote:
> On Mon, Mar 02, 2015 at 08:15:59PM +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.
> > 
> > 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)
> 
> The commit this is fixing is in v3.19 so this should go to stable but I
> can't apply this against my fix/dw branch.  Can you generate a version
> that can be applied there please?  We'll need to work out the merge
> issues with the current code I gues...


Hmm… Just tried apply on top on fix/dw using

git am -C1 -s
0001-spi-dw-mid-clear-BUSY-flag-fist-and-test-other-one.patch

It went fine with reduced context.

Shall I still resend you that version?
Mark Brown March 7, 2015, 11:04 a.m. UTC | #3
On Fri, Mar 06, 2015 at 02:40:29PM +0200, Andy Shevchenko wrote:
> On Fri, 2015-03-06 at 11:25 +0000, Mark Brown wrote:

> > The commit this is fixing is in v3.19 so this should go to stable but I
> > can't apply this against my fix/dw branch.  Can you generate a version
> > that can be applied there please?  We'll need to work out the merge
> > issues with the current code I gues...

> Hmm… Just tried apply on top on fix/dw using

> git am -C1 -s
> 0001-spi-dw-mid-clear-BUSY-flag-fist-and-test-other-one.patch

> It went fine with reduced context.

> Shall I still resend you that version?

Yes, please resend.
diff mbox

Patch

diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index a8a5ee3..c8416ef 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;
 	spi_finalize_current_transfer(dws->master);
 }
@@ -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;
 	spi_finalize_current_transfer(dws->master);
 }