[PATCH v5 01/14] dmaengine: dw-edma: Factor out HDMA interrupt setup helper

From: Koichiro Den

Date: Fri Jul 17 2026 - 01:03:44 EST


The HDMA linked-list and non-linked-list start paths both program the
stop/abort interrupt setup register using the same local/remote enable
policy. Only the interrupt-mask handling differs by transfer mode.

Factor the common setup into dw_hdma_v0_core_int_setup() before adding
per-channel interrupt routing support. No functional change intended.

Suggested-by: Frank Li <Frank.Li@xxxxxxx>
Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
Changes in v5:
- No changes.

drivers/dma/dw-edma/dw-hdma-v0-core.c | 34 ++++++++++++++-------------
1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/dma/dw-edma/dw-hdma-v0-core.c b/drivers/dma/dw-edma/dw-hdma-v0-core.c
index 4bf5a441afbf..b455da3d9b0f 100644
--- a/drivers/dma/dw-edma/dw-hdma-v0-core.c
+++ b/drivers/dma/dw-edma/dw-hdma-v0-core.c
@@ -49,6 +49,21 @@ __dw_ch_regs(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch)
writel(value, &(__dw_ch_regs(dw, EDMA_DIR_READ, ch)->name)); \
} while (0)

+static u32 dw_hdma_v0_core_int_setup(struct dw_edma_chan *chan, u32 val)
+{
+ if (chan->non_ll)
+ val |= HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK;
+ else
+ val &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+
+ val |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
+ if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
+ val |= HDMA_V0_REMOTE_STOP_INT_EN |
+ HDMA_V0_REMOTE_ABORT_INT_EN;
+
+ return val;
+}
+
/* HDMA management callbacks */
static void dw_hdma_v0_core_off(struct dw_edma *dw)
{
@@ -203,11 +218,7 @@ static void dw_hdma_v0_core_ch_enable(struct dw_edma_chan *chan)
SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0));
/* Interrupt unmask - stop, abort */
tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup);
- tmp &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
- /* Interrupt enable - stop, abort */
- tmp |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
- if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL))
- tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN;
+ tmp = dw_hdma_v0_core_int_setup(chan, tmp);
SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp);
/* Channel control */
SET_CH_32(dw, chan->dir, chan->id, control1, HDMA_V0_LINKLIST_EN);
@@ -260,17 +271,8 @@ static void dw_hdma_v0_core_non_ll_start(struct dw_edma_chan *chan,
SET_CH_32(dw, chan->dir, chan->id, transfer_size, child->sz);

/* Interrupt setup */
- val = GET_CH_32(dw, chan->dir, chan->id, int_setup) |
- HDMA_V0_STOP_INT_MASK |
- HDMA_V0_ABORT_INT_MASK |
- HDMA_V0_LOCAL_STOP_INT_EN |
- HDMA_V0_LOCAL_ABORT_INT_EN;
-
- if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL)) {
- val |= HDMA_V0_REMOTE_STOP_INT_EN |
- HDMA_V0_REMOTE_ABORT_INT_EN;
- }
-
+ val = GET_CH_32(dw, chan->dir, chan->id, int_setup);
+ val = dw_hdma_v0_core_int_setup(chan, val);
SET_CH_32(dw, chan->dir, chan->id, int_setup, val);

/* Channel control setup */
--
2.51.0