[PATCH 6/6] drm/vc4: Let runtime PM tear the V3D down at unbind

Maíra Canal <[email protected]>
Newsgroups org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.