[PATCH v3 4/5] dmaengine: mcf-edma: Fix error handler for all 64 DMA channels

From: Jean-Michel Hautbois

Date: Thu Jun 25 2026 - 05:05:18 EST


Fix the DMA error interrupt handler to properly handle errors on all
64 channels. The previous implementation had several issues:

1. Returned IRQ_NONE if low channels had no errors, even if high
channels did
2. Used direct status assignment instead of fsl_edma_err_chan_handler()
for high channels

Split the error handling into two separate loops for the low (0-31)
and high (32-63) channel groups, using for_each_set_bit() for cleaner
iteration. Both groups now consistently use fsl_edma_err_chan_handler()
for proper error status reporting.

Fixes: e7a3ff92eaf1 ("dmaengine: fsl-edma: add ColdFire mcf5441x edma support")
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@xxxxxxxxxx>
---
drivers/dma/mcf-edma-main.c | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/dma/mcf-edma-main.c b/drivers/dma/mcf-edma-main.c
index 953b20f99f25..3dab5d475d1b 100644
--- a/drivers/dma/mcf-edma-main.c
+++ b/drivers/dma/mcf-edma-main.c
@@ -42,30 +42,22 @@ static irqreturn_t mcf_edma_err_handler(int irq, void *dev_id)
{
struct fsl_edma_engine *mcf_edma = dev_id;
struct edma_regs *regs = &mcf_edma->regs;
- unsigned int err, ch;
+ unsigned long ch;
+ DECLARE_BITMAP(err_mask, 64);
+ u64 errmap;

- err = ioread32(regs->errl);
- if (!err)
+ errmap = ioread32(regs->errh);
+ errmap <<= 32;
+ errmap |= ioread32(regs->errl);
+ if (!errmap)
return IRQ_NONE;

- for (ch = 0; ch < (EDMA_CHANNELS / 2); ch++) {
- if (err & BIT(ch)) {
- fsl_edma_disable_request(&mcf_edma->chans[ch]);
- iowrite8(EDMA_CERR_CERR(ch), regs->cerr);
- fsl_edma_err_chan_handler(&mcf_edma->chans[ch]);
- }
- }
-
- err = ioread32(regs->errh);
- if (!err)
- return IRQ_NONE;
+ bitmap_from_u64(err_mask, errmap);

- for (ch = (EDMA_CHANNELS / 2); ch < EDMA_CHANNELS; ch++) {
- if (err & (BIT(ch - (EDMA_CHANNELS / 2)))) {
- fsl_edma_disable_request(&mcf_edma->chans[ch]);
- iowrite8(EDMA_CERR_CERR(ch), regs->cerr);
- mcf_edma->chans[ch].status = DMA_ERROR;
- }
+ for_each_set_bit(ch, err_mask, mcf_edma->n_chans) {
+ fsl_edma_disable_request(&mcf_edma->chans[ch]);
+ iowrite8(EDMA_MASK_CH(ch), regs->cerr);
+ fsl_edma_err_chan_handler(&mcf_edma->chans[ch]);
}

return IRQ_HANDLED;

--
2.39.5