vc4_v3d_unbind() clears the binner overflow address and size and calls
vc4_irq_uninstall() to mask the interrupts. Both access V3D registers
without a runtime PM reference, and the block has usually autosuspended
before unbind runs.

Neither is needed: vc4_v3d_bind() already clears the overflow pair and
vc4_v3d_runtime_suspend() already masks the interrupts. Suspend the block
instead, before vc4->v3d is cleared, and drop vc4_irq_uninstall() with it.

In the bind path, arming the interrupts already happens during PM resume,
so vc4_irq_install() has nothing left to do but register the handler. It
no longer needs the block to be powered, so move it ahead of the runtime PM
enable in vc4_v3d_bind().

Signed-off-by: Maíra Canal <[email protected]>
---
 drivers/gpu/drm/vc4/vc4_drv.h |  1 -
 drivers/gpu/drm/vc4/vc4_irq.c | 21 ++-------------------
 drivers/gpu/drm/vc4/vc4_v3d.c | 21 +++++++--------------
 3 files changed, 9 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 38f539cb49f4..128358f27a2d 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -1016,7 +1016,6 @@ extern struct platform_driver vc4_txp_driver;
 void vc4_irq_enable(struct drm_device *dev);
 void vc4_irq_disable(struct drm_device *dev);
 int vc4_irq_install(struct drm_device *dev);
-void vc4_irq_uninstall(struct drm_device *dev);
 void vc4_irq_reset(struct drm_device *dev);
 
 /* vc4_hvs.c */
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 999010381da1..7ffd6a1c2fc6 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -296,7 +296,6 @@ vc4_irq_disable(struct drm_device *dev)
 int vc4_irq_install(struct drm_device *dev)
 {
        struct vc4_dev *vc4 = to_vc4_dev(dev);
-       int ret;
 
        if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
                return -ENODEV;
@@ -307,24 +306,8 @@ int vc4_irq_install(struct drm_device *dev)
        init_waitqueue_head(&vc4->job_wait_queue);
        INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work);
 
-       ret = devm_request_irq(dev->dev, vc4->irq, vc4_irq, 0,
-                              dev_name(dev->dev), dev);
-       if (ret)
-               return ret;
-
-       vc4_irq_enable(dev);
-
-       return 0;
-}
-
-void vc4_irq_uninstall(struct drm_device *dev)
-{
-       struct vc4_dev *vc4 = to_vc4_dev(dev);
-
-       if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
-               return;
-
-       vc4_irq_disable(dev);
+       return devm_request_irq(dev->dev, vc4->irq, vc4_irq, 0,
+                               dev_name(dev->dev), dev);
 }
 
 /** Reinitializes interrupt registers when a GPU reset is performed. */
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 818997ded33a..890225ae485d 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -445,6 +445,12 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
                return ret;
        vc4->irq = ret;
 
+       ret = vc4_irq_install(drm);
+       if (ret) {
+               drm_err(drm, "Failed to install IRQ handler\n");
+               return ret;
+       }
+
        ret = devm_pm_runtime_enable(dev);
        if (ret)
                return ret;
@@ -466,12 +472,6 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
        V3D_WRITE(V3D_BPOA, 0);
        V3D_WRITE(V3D_BPOS, 0);
 
-       ret = vc4_irq_install(drm);
-       if (ret) {
-               drm_err(drm, "Failed to install IRQ handler\n");
-               goto err_put_runtime_pm;
-       }
-
        pm_runtime_use_autosuspend(dev);
        pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
        pm_runtime_put_autosuspend(dev);
@@ -490,14 +490,7 @@ static void vc4_v3d_unbind(struct device *dev, struct 
device *master,
        struct drm_device *drm = dev_get_drvdata(master);
        struct vc4_dev *vc4 = to_vc4_dev(drm);
 
-       vc4_irq_uninstall(drm);
-
-       /* Disable the binner's overflow memory address, so the next
-        * driver probe (if any) doesn't try to reuse our old
-        * allocation.
-        */
-       V3D_WRITE(V3D_BPOA, 0);
-       V3D_WRITE(V3D_BPOS, 0);
+       pm_runtime_suspend(dev);
 
        vc4->v3d = NULL;
 }

-- 
2.55.0

Reply via email to