diff mbox

dma: ep93xx: Treat STALL and NFB IRQs same way

Message ID 568EE13C.7090500@gmx.de (mailing list archive)
State Accepted
Headers show

Commit Message

Alexander Sverdlin Jan. 7, 2016, 10:05 p.m. UTC
Debugging ALSA hangups it was found that EP9302 (latest E2 rev.) DMA controller
sometimes asserts STALL interrupt instead of NFB interrupt. Simply ignoring the
difference and simply acting upon the amount of data we still have to transfer
seems to work fine. This somehow sounds similar to M2M issue which is already
dealt with in the driver, when the controller asserts DONE interrupt too early.

The issue is not documented in Cirrus Logic erratas for EP93XX, but original
Cirrus DMA driver from 2003 (not based on DMA API) did the similar handling
of STALL interrupt. In-tree driver (6d831c65) did it also, before conversion to
DMA engine API.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 drivers/dma/ep93xx_dma.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Vinod Koul Jan. 13, 2016, 1:27 p.m. UTC | #1
On Thu, Jan 07, 2016 at 11:05:48PM +0100, Alexander Sverdlin wrote:
> Debugging ALSA hangups it was found that EP9302 (latest E2 rev.) DMA controller
> sometimes asserts STALL interrupt instead of NFB interrupt. Simply ignoring the
> difference and simply acting upon the amount of data we still have to transfer
> seems to work fine. This somehow sounds similar to M2M issue which is already
> dealt with in the driver, when the controller asserts DONE interrupt too early.
> 
> The issue is not documented in Cirrus Logic erratas for EP93XX, but original
> Cirrus DMA driver from 2003 (not based on DMA API) did the similar handling
> of STALL interrupt. In-tree driver (6d831c65) did it also, before conversion to
> DMA engine API.

Applied after fixing subsystem name
diff mbox

Patch

diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 57ff462..21f08cc 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -421,23 +421,25 @@  static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac)
 			desc->size);
 	}

-	switch (irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) {
-	case M2P_INTERRUPT_STALL:
-		/* Disable interrupts */
-		control = readl(edmac->regs + M2P_CONTROL);
-		control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT);
-		m2p_set_control(edmac, control);
-
-		return INTERRUPT_DONE;
-
-	case M2P_INTERRUPT_NFB:
-		if (ep93xx_dma_advance_active(edmac))
-			m2p_fill_desc(edmac);
+	/*
+	 * Even latest E2 silicon revision sometimes assert STALL interrupt
+	 * instead of NFB. Therefore we treat them equally, basing on the
+	 * amount of data we still have to transfer.
+	 */
+	if (!(irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)))
+		return INTERRUPT_UNKNOWN;

+	if (ep93xx_dma_advance_active(edmac)) {
+		m2p_fill_desc(edmac);
 		return INTERRUPT_NEXT_BUFFER;
 	}

-	return INTERRUPT_UNKNOWN;
+	/* Disable interrupts */
+	control = readl(edmac->regs + M2P_CONTROL);
+	control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT);
+	m2p_set_control(edmac, control);
+
+	return INTERRUPT_DONE;
 }

 /*