Re: [PATCH v12 06/15] drm/panfrost: Fix PM refcnt and autosuspend issues at device probe/remove
From: Steven Price
Date: Fri Oct 02 2026 - 10:23:15 EST
On 29/09/2026 04:44, Adrián Larumbe wrote:
> 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 outcome of both of the above meant 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.
> - Because MMU interrupts are only enabled when the device is reset,
> the very first job targeting the tiler heap BO after device probe()
> would always time out, since the driver's PM runtime resume callback
> would not be invoked.
>
> To fix the above:
> - Manually adjust the PM refcnt at device probe and removal time.
> - Ensure pm_runtime_dont_use_autosuspend is called in the wind-down path.
> - Call pm_runtime_put_autosuspend() when device is ready to accept jobs
>
> Signed-off-by: Adrián Larumbe <adrian.larumbe@xxxxxxxxxxxxx>
> Fixes: 635430797d3f ("drm/panfrost: Rework runtime PM initialization")
> Fixes: 876b15d2c88d ("drm/panfrost: Fix module unload")
Reviewed-by: Steven Price <steven.price@xxxxxxx>
> ---
> drivers/gpu/drm/panfrost/panfrost_drv.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 55fc22e8d4d4..907d4a14a0b5 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -852,6 +852,11 @@ static int panfrost_probe(struct platform_device *pdev)
> goto err_out0;
> }
>
> + /* The reason we must manually set the PM status and usage counter is
> + * we have just powered the device up but did not go through the PM
> + * runtime resume callback, so we need to update these ourselves.
> + */
> + pm_runtime_get_noresume(pfdev->base.dev);
> pm_runtime_set_active(pfdev->base.dev);
> pm_runtime_mark_last_busy(pfdev->base.dev);
> pm_runtime_enable(pfdev->base.dev);
> @@ -866,13 +871,16 @@ 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_dont_use_autosuspend(pfdev->base.dev);
> pm_runtime_disable(pfdev->base.dev);
> panfrost_device_fini(pfdev);
> pm_runtime_set_suspended(pfdev->base.dev);
> + pm_runtime_put_noidle(pfdev->base.dev);
> err_out0:
> return err;
> }
> @@ -884,9 +892,12 @@ static void panfrost_remove(struct platform_device *pdev)
> drm_dev_unregister(&pfdev->base);
>
> pm_runtime_get_sync(pfdev->base.dev);
> + pm_runtime_dont_use_autosuspend(pfdev->base.dev);
> pm_runtime_disable(pfdev->base.dev);
> panfrost_device_fini(pfdev);
> pm_runtime_set_suspended(pfdev->base.dev);
> + pm_runtime_put_noidle(pfdev->base.dev);
> +
> }
>
> static ssize_t profiling_show(struct device *dev,
>