]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/panthor: Keep interrupts masked until they are needed
authorBoris Brezillon <boris.brezillon@collabora.com>
Thu, 25 Jun 2026 12:40:37 +0000 (14:40 +0200)
committerLiviu Dudau <liviu.dudau@arm.com>
Tue, 30 Jun 2026 14:26:55 +0000 (15:26 +0100)
The autogenerated panthor_request_xx_irq() helpers unmask Mali
interrupts before we're sure we'll have a handler registered. For
non-shared IRQ lines, that's fine, but for shared ones, it might cause
an interrupt flood if the HW block raises an interrupt for any reason.

We could reworking the calls in panthor_request_xx_irq(), but it's just
simpler to let the caller decide when they are ready to handle interrupts
and call panthor_pwr_irq_resume() themselves. While at it, rework the
prototype to let users call panthor_pwr_irq_enable_events() explicitly
instead of passing an initial mask to panthor_request_pwr_irq().

Fixes: 5fe909cae118 ("drm/panthor: Add the device logical block")
Reported-by: Shashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260623-panthor-signal-from-irq-v3-0-2ece396f8ee0@collabora.com?part=3
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Karunika Choo <karunika.choo@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Link: https://patch.msgid.link/20260625-panthor-misc-fixes-v1-11-b67ed973fea6@collabora.com
drivers/gpu/drm/panthor/panthor_device.h
drivers/gpu/drm/panthor/panthor_fw.c
drivers/gpu/drm/panthor/panthor_gpu.c
drivers/gpu/drm/panthor/panthor_mmu.c
drivers/gpu/drm/panthor/panthor_pwr.c

index 291e0de154bcb196514633b173b97b048d67ec8e..98828e81db0b4a36e868f083e09b26f42b2bed90 100644 (file)
@@ -585,14 +585,15 @@ static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *pirq)
                                                                                                \
 static int panthor_request_ ## __name ## _irq(struct panthor_device *ptdev,                    \
                                              struct panthor_irq *pirq,                         \
-                                             int irq, u32 mask, void __iomem *iomem)           \
+                                             int irq, void __iomem *iomem)                     \
 {                                                                                              \
        pirq->ptdev = ptdev;                                                                    \
        pirq->irq = irq;                                                                        \
-       pirq->mask = mask;                                                                      \
+       pirq->mask = 0;                                                                         \
        pirq->iomem = iomem;                                                                    \
        spin_lock_init(&pirq->mask_lock);                                                       \
-       panthor_ ## __name ## _irq_resume(pirq);                                                \
+       atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED);                                  \
+       gpu_write(pirq->iomem, INT_MASK, 0);                                                    \
                                                                                                \
        return devm_request_threaded_irq(ptdev->base.dev, irq,                                  \
                                         panthor_ ## __name ## _irq_raw_handler,                \
index 4fbddb9e18c8b3d99c072e7b2c099069d443196f..de8e6689a869a066423c47296596746fd94567b4 100644 (file)
@@ -1474,7 +1474,7 @@ int panthor_fw_init(struct panthor_device *ptdev)
        if (irq <= 0)
                return -ENODEV;
 
-       ret = panthor_request_job_irq(ptdev, &fw->irq, irq, 0,
+       ret = panthor_request_job_irq(ptdev, &fw->irq, irq,
                                      ptdev->iomem + JOB_INT_BASE);
        if (ret) {
                drm_err(&ptdev->base, "failed to request job irq");
index e52c5675981f5ec342247ce29623ae8a9a648eb0..c013d6bf9a599e61282b1bbdd8af895a6f16514d 100644 (file)
@@ -170,11 +170,12 @@ int panthor_gpu_init(struct panthor_device *ptdev)
                return irq;
 
        ret = panthor_request_gpu_irq(ptdev, &ptdev->gpu->irq, irq,
-                                     GPU_INTERRUPTS_MASK,
                                      ptdev->iomem + GPU_INT_BASE);
        if (ret)
                return ret;
 
+       panthor_gpu_irq_enable_events(&ptdev->gpu->irq, GPU_INTERRUPTS_MASK);
+       panthor_gpu_irq_resume(&ptdev->gpu->irq);
        return 0;
 }
 
index dab6840e88575a3ff8712df60fe972bd2d962dbd..e592a8ebb47809f284baab159161b05f5b2c6ff0 100644 (file)
@@ -3262,7 +3262,6 @@ int panthor_mmu_init(struct panthor_device *ptdev)
                return -ENODEV;
 
        ret = panthor_request_mmu_irq(ptdev, &mmu->irq, irq,
-                                     panthor_mmu_fault_mask(ptdev, ~0),
                                      ptdev->iomem + MMU_INT_BASE);
        if (ret)
                return ret;
@@ -3280,7 +3279,13 @@ int panthor_mmu_init(struct panthor_device *ptdev)
                ptdev->gpu_info.mmu_features |= BITS_PER_LONG;
        }
 
-       return drmm_add_action_or_reset(&ptdev->base, panthor_mmu_release_wq, mmu->vm.wq);
+       ret = drmm_add_action_or_reset(&ptdev->base, panthor_mmu_release_wq, mmu->vm.wq);
+       if (ret)
+               return ret;
+
+       panthor_mmu_irq_enable_events(&mmu->irq, panthor_mmu_fault_mask(ptdev, ~0));
+       panthor_mmu_irq_resume(&mmu->irq);
+       return 0;
 }
 
 #ifdef CONFIG_DEBUG_FS
index 090362bd700b15158e8709b0ec4ce6f7ae89b04e..f2c2c300059051f39da8d120ba70b689a82caa07 100644 (file)
@@ -484,12 +484,13 @@ int panthor_pwr_init(struct panthor_device *ptdev)
        if (irq < 0)
                return irq;
 
-       err = panthor_request_pwr_irq(
-               ptdev, &pwr->irq, irq, PWR_INTERRUPTS_MASK,
-               pwr->iomem + PWR_INT_BASE);
+       err = panthor_request_pwr_irq(ptdev, &pwr->irq, irq,
+                                     pwr->iomem + PWR_INT_BASE);
        if (err)
                return err;
 
+       panthor_pwr_irq_enable_events(&pwr->irq, PWR_INTERRUPTS_MASK);
+       panthor_pwr_irq_resume(&pwr->irq);
        return 0;
 }