[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