drm/panthor: Be robust against runtime PM resume failures in the suspend path
authorBoris Brezillon <boris.brezillon@collabora.com>
Wed, 11 Dec 2024 07:54:16 +0000 (08:54 +0100)
committerBoris Brezillon <boris.brezillon@collabora.com>
Wed, 11 Dec 2024 09:03:54 +0000 (10:03 +0100)
The runtime PM resume operation is not guaranteed to succeed, but if it
fails, the device should be in a suspended state. Make sure we're robust
to resume failures in the unplug path.

v3:
- Fix typo
- Add R-bs

v2:
- Move the bit that belonged in the next commit
- Drop the panthor_device_unplug() changes

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Adrian Larumbe <adrian.larumbe@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241211075419.2333731-3-boris.brezillon@collabora.com
drivers/gpu/drm/panthor/panthor_fw.c
drivers/gpu/drm/panthor/panthor_gpu.c
drivers/gpu/drm/panthor/panthor_mmu.c

index 4a2e36504feab3c24d39a6f4c092fea2c8195ad1..7cdf251281977b561c63130d503853063b03f4e2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/iosys-map.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include <drm/drm_drv.h>
 #include <drm/drm_managed.h>
@@ -1190,11 +1191,13 @@ void panthor_fw_unplug(struct panthor_device *ptdev)
 
        cancel_delayed_work_sync(&ptdev->fw->watchdog.ping_work);
 
-       /* Make sure the IRQ handler can be called after that point. */
-       if (ptdev->fw->irq.irq)
-               panthor_job_irq_suspend(&ptdev->fw->irq);
+       if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev)) {
+               /* Make sure the IRQ handler cannot be called after that point. */
+               if (ptdev->fw->irq.irq)
+                       panthor_job_irq_suspend(&ptdev->fw->irq);
 
-       panthor_fw_stop(ptdev);
+               panthor_fw_stop(ptdev);
+       }
 
        list_for_each_entry(section, &ptdev->fw->sections, node)
                panthor_kernel_bo_destroy(section->mem);
@@ -1207,7 +1210,8 @@ void panthor_fw_unplug(struct panthor_device *ptdev)
        panthor_vm_put(ptdev->fw->vm);
        ptdev->fw->vm = NULL;
 
-       panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000);
+       if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev))
+               panthor_gpu_power_off(ptdev, L2, ptdev->gpu_info.l2_present, 20000);
 }
 
 /**
index 0f3cac6ec88e7bf154428a049e400032f12d4f80..ee85a371bc3892138befa52810c4103d3e9e90ac 100644 (file)
@@ -180,7 +180,8 @@ void panthor_gpu_unplug(struct panthor_device *ptdev)
        unsigned long flags;
 
        /* Make sure the IRQ handler is not running after that point. */
-       panthor_gpu_irq_suspend(&ptdev->gpu->irq);
+       if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev))
+               panthor_gpu_irq_suspend(&ptdev->gpu->irq);
 
        /* Wake-up all waiters. */
        spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
index c3f0b0225cf9028f2ad422f629c1d5ec547ee34b..c39e3eb1c15d53ed4c2fe530463d8df3a4900a08 100644 (file)
@@ -2672,7 +2672,8 @@ int panthor_vm_prepare_mapped_bos_resvs(struct drm_exec *exec, struct panthor_vm
  */
 void panthor_mmu_unplug(struct panthor_device *ptdev)
 {
-       panthor_mmu_irq_suspend(&ptdev->mmu->irq);
+       if (!IS_ENABLED(CONFIG_PM) || pm_runtime_active(ptdev->base.dev))
+               panthor_mmu_irq_suspend(&ptdev->mmu->irq);
 
        mutex_lock(&ptdev->mmu->as.slots_lock);
        for (u32 i = 0; i < ARRAY_SIZE(ptdev->mmu->as.slots); i++) {