[PATCH] dmaengine: sun6i: Fix physical channel index in interrupt handler

Hongling Zeng zenghongling at kylinos.cn
Sun Jul 5 23:41:23 PDT 2026


The interrupt handler iterates over register banks in the outer loop
(i = 0, 1, ...), where each bank covers DMA_IRQ_CHAN_NR (8) channels.
However, the physical channel lookup uses only the inner loop index j,
ignoring the bank offset i.

This means for SoCs with more than 8 DMA channels, interrupts from
physical channels 8 and above are incorrectly routed to physical
channels 0-7. This can falsely complete descriptors for unrelated
channels, potentially causing silent memory corruption.

Fix by using the absolute channel index (i * DMA_IRQ_CHAN_NR + j).

Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Cc: stable at vger.kernel.org
Signed-off-by: Hongling Zeng <zenghongling at kylinos.cn>
---
 drivers/dma/sun6i-dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index a6487971ad09..fcc88a74d821 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -559,7 +559,7 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id)
 		writel(status, sdev->base + DMA_IRQ_STAT(i));
 
 		for (j = 0; (j < DMA_IRQ_CHAN_NR) && status; j++) {
-			pchan = sdev->pchans + j;
+			pchan = sdev->pchans + i * DMA_IRQ_CHAN_NR + j;
 			vchan = pchan->vchan;
 			if (vchan && (status & vchan->irq_type)) {
 				if (vchan->cyclic) {
-- 
2.25.1




More information about the linux-arm-kernel mailing list