During device probe(), failure to do a PM get() will leave the usage_count set to 0, which is the value assigned at device creation time. That means when the autosuspend delay expires, runtime suspend callback won't be invoked, so the device will remain powered on forever.
On top of that, failure to call PM put() during device unplug means Panfrost device's PM usage_count increases monotonically for every new module reload. The combined outcome of both of the above was that devfreq OPP transition notifications would be printed all the time, even when no jobs are being submitted. This quickly fills the kernel ring buffer with junk. Even direr than that was the fact MMU interrupts are only enabled when the device is reset, so after device probe() the very first job targeting the tiler heap BO would always time out, because the driver's PM runtime resume callback would not be invoked. Signed-off-by: Adrián Larumbe <[email protected]> Fixes: 635430797d3f ("drm/panfrost: Rework runtime PM initialization") Fixes: 876b15d2c88d ("drm/panfrost: Fix module unload") --- drivers/gpu/drm/panfrost/panfrost_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 2d4b6aa95c66..545fbf2c8d0c 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -989,6 +989,7 @@ static int panfrost_probe(struct platform_device *pdev) pm_runtime_set_active(pfdev->base.dev); pm_runtime_mark_last_busy(pfdev->base.dev); pm_runtime_enable(pfdev->base.dev); + pm_runtime_get_noresume(pfdev->base.dev); pm_runtime_set_autosuspend_delay(pfdev->base.dev, 50); /* ~3 frames */ pm_runtime_use_autosuspend(pfdev->base.dev); @@ -1000,10 +1001,12 @@ static int panfrost_probe(struct platform_device *pdev) if (err < 0) goto err_out1; + pm_runtime_put_autosuspend(pfdev->base.dev); return 0; err_out1: + pm_runtime_put_noidle(pfdev->base.dev); pm_runtime_disable(pfdev->base.dev); panfrost_device_fini(pfdev); pm_runtime_set_suspended(pfdev->base.dev); @@ -1018,8 +1021,9 @@ static void panfrost_remove(struct platform_device *pdev) drm_dev_unregister(&pfdev->base); pm_runtime_get_sync(pfdev->base.dev); - pm_runtime_disable(pfdev->base.dev); panfrost_device_fini(pfdev); + pm_runtime_put_noidle(pfdev->base.dev); + pm_runtime_disable(pfdev->base.dev); pm_runtime_set_suspended(pfdev->base.dev); } -- 2.53.0
