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.

Reported-by: [email protected]
Closes: 
https://lore.kernel.org/dmaengine/[email protected]/
Assisted-by: Codex:gpt-5-5
Signed-off-by: Linus Walleij <[email protected]>
---
 drivers/dma/ste_dma40.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index facc1bcf42a0..dd449d4285ef 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -1674,6 +1674,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 (ret <= 0)
+               return IRQ_NONE;
 
        spin_lock(&base->interrupt_lock);
 
@@ -1722,6 +1727,8 @@ static irqreturn_t d40_handle_interrupt(int irq, void 
*data)
 
        spin_unlock(&base->interrupt_lock);
 
+       pm_runtime_put_autosuspend(base->dev);
+
        return IRQ_HANDLED;
 }
 

-- 
2.55.0


Reply via email to