[PATCH v1 05/11] media: intel/ipu6: check irq_status mask before calling subdevice ISR

From: Valerii Sokolov

Date: Fri Oct 23 2026 - 16:05:07 EST


In ipu6_buttress_isr(), ipu6_buttress_call_isr(adev[i]) is called at the
start of each loop iteration, before checking whether irq_status has the
corresponding auxiliary device interrupt bit (adev_irq_mask[i]) set.

As a result, the ISYS and PSYS ISRs run on every Buttress interrupt
regardless of its source, and their return value is then discarded by
the continue statement. For the ISYS this means ipu6_isys_isr() taking a
runtime PM reference, masking and unmasking the UNISPART interrupts and
draining the firmware response queue on interrupts not meant for it.

Check irq_status against adev_irq_mask[i] before calling
ipu6_buttress_call_isr(adev[i]).

Fixes: ab29a2478e70 ("media: intel/ipu6: add IPU6 buttress interface driver")
Signed-off-by: Valerii Sokolov <valerii.sokolov@xxxxx>
---
drivers/media/pci/intel/ipu6/ipu6-buttress.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
index f1d236054c..debc4ac929 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
@@ -364,11 +364,12 @@ irqreturn_t ipu6_buttress_isr(int irq, void *isp_ptr)
writel(irq_status, isp->base + regs->irq_clear);

for (i = 0; i < ARRAY_SIZE(adev_irq_mask); i++) {
- irqreturn_t r = ipu6_buttress_call_isr(adev[i]);
+ irqreturn_t r;

if (!(irq_status & adev_irq_mask[i]))
continue;

+ r = ipu6_buttress_call_isr(adev[i]);
if (r == IRQ_WAKE_THREAD) {
ret = IRQ_WAKE_THREAD;
disable_irqs |= adev_irq_mask[i];
--
2.56.0