dmaengine: ste_dma40: Check runtime PM in IRQ

d40_handle_interrupt() reads DMA40 interrupt registers unconditionally. A
spurious interrupt can arrive while the device is runtime suspended, after
dma40_runtime_suspend() has disabled the GCC clock.

Avoid touching the registers unless the device is runtime active by taking
a conditional runtime PM reference. Return IRQ_NONE when the device is
suspended, and drop the reference after handling an active interrupt.

When CONFIG_PM is disabled, pm_runtime_get_if_active() returns -EINVAL even
though the registers remain accessible. Keep handling interrupts in that
configuration and only drop the runtime PM reference when one was acquired.

Fixes: 7fb3e75e18 ("dmaengine/ste_dma40: support pm in dma40")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/dmaengine/20260819225114.AE1511F000E9@smtp.kernel.org/
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260927-dma40-fixes-v7-6-89f595e8851d@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Linus Walleij 2026-09-27 11:03:19 +02:00 committed by Vinod Koul
parent c6809b381e
commit 12787e3f2f

View File

@ -1802,6 +1802,11 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data)
u32 *regs = base->regs_interrupt;
struct d40_interrupt_lookup *il = base->gen_dmac.il;
u32 il_size = base->gen_dmac.il_size;
int ret;
ret = pm_runtime_get_if_active(base->dev);
if (IS_ENABLED(CONFIG_PM) && ret <= 0)
return IRQ_NONE;
spin_lock(&base->interrupt_lock);
@ -1850,6 +1855,9 @@ static irqreturn_t d40_handle_interrupt(int irq, void *data)
spin_unlock(&base->interrupt_lock);
if (ret > 0)
pm_runtime_put_autosuspend(base->dev);
return IRQ_HANDLED;
}