diff mbox

[05/10] spi: dw: disable all interrupts first when pump message

Message ID 1411060140-2801-6-git-send-email-andriy.shevchenko@linux.intel.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Andy Shevchenko Sept. 18, 2014, 5:08 p.m. UTC
Always disable all interrupts before pump message. Enable them only for PIO
mode.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-dw.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

Comments

Mark Brown Sept. 24, 2014, 8:47 a.m. UTC | #1
On Thu, Sep 18, 2014 at 08:08:55PM +0300, Andy Shevchenko wrote:

> Always disable all interrupts before pump message. Enable them only for PIO
> mode.

Why?  

It's also not very obvious looking at the diff how this actually works,
the connection between DMA based transfer and interrupt disabling is
not clear.
Andy Shevchenko Sept. 24, 2014, 10:38 a.m. UTC | #2
On Wed, 2014-09-24 at 09:47 +0100, Mark Brown wrote:
> On Thu, Sep 18, 2014 at 08:08:55PM +0300, Andy Shevchenko wrote:
> 
> > Always disable all interrupts before pump message. Enable them only for PIO
> > mode.
> 
> Why?  
> 
> It's also not very obvious looking at the diff how this actually works,
> the connection between DMA based transfer and interrupt disabling is
> not clear.

It's a really good question and needs to be investigated more.

If I don't disable interrupts I'm getting sometimes overrun/underrun
interrupt. But we have no proper transfer handler in case of DMA.

Perhaps we should carefully handle that case.
diff mbox

Patch

diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 0960cc7..d58edfe 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -342,6 +342,13 @@  static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 	return dws->transfer_handler(dws);
 }
 
+static void dw_spi_disable_intr(struct dw_spi *dws)
+{
+	spi_enable_chip(dws, 0);
+	spi_mask_intr(dws, 0xff);
+	spi_enable_chip(dws, 1);
+}
+
 /* Must be called inside pump_transfers() */
 static void poll_transfer(struct dw_spi *dws)
 {
@@ -474,6 +481,9 @@  static void pump_transfers(unsigned long data)
 		dws->transfer_handler = interrupt_transfer;
 	}
 
+	/* Disable all interrupts first */
+	dw_spi_disable_intr(dws);
+
 	/*
 	 * Reprogram registers only if
 	 *	1. chip select changes
@@ -490,7 +500,6 @@  static void pump_transfers(unsigned long data)
 		spi_chip_sel(dws, spi, 1);
 
 		/* Set the interrupt mask, for poll mode just disable all int */
-		spi_mask_intr(dws, 0xff);
 		if (imask)
 			spi_umask_intr(dws, imask);
 		if (txint_level)
@@ -611,9 +620,7 @@  static void dw_spi_cleanup(struct spi_device *spi)
 /* Restart the controller, disable all interrupts, clean rx fifo */
 static void spi_hw_init(struct dw_spi *dws)
 {
-	spi_enable_chip(dws, 0);
-	spi_mask_intr(dws, 0xff);
-	spi_enable_chip(dws, 1);
+	dw_spi_disable_intr(dws);
 
 	/*
 	 * Try to detect the FIFO depth if not set by interface driver,