Re: [PATCH v2 8/8] PM: runtime: Add Example Driver Patterns section
From: Ulf Hansson
Date: Thu Sep 24 2026 - 10:32:30 EST
On Wed, Sep 23, 2026 at 7:48 PM Brian Norris <briannorris@xxxxxxxxxxxx> wrote:
>
> The runtime PM API surface is pretty large, but there are a few common
> patterns that many drivers should follow. Add some illustrative
> examples, to help guide the most common audience for runtime PM docs --
> driver writers.
>
> Signed-off-by: Brian Norris <briannorris@xxxxxxxxxxxx>
> ---
>
> Changes in v2:
> * Add appropriate teardown to "Probe with Hardware Powered Off"
> Example, as the remove() + power-off behavior is subtle here, and
> easy to get wrong
>
> Documentation/power/runtime_pm.rst | 367 ++++++++++++++++++++++++++++-
> 1 file changed, 366 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst
> index 7bb64d793cdd..3a615d2de103 100644
> --- a/Documentation/power/runtime_pm.rst
> +++ b/Documentation/power/runtime_pm.rst
> @@ -641,7 +641,9 @@ The implementation is well suited for asynchronous use in interrupt contexts.
> However such use inevitably involves races, because the PM core can't
> synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
> This synchronization must be handled by the driver, using its private lock.
> -Here is a schematic pseudo-code example::
> +Here is a schematic pseudo-code example:
> +
> +.. code-block:: c
>
> foo_read_or_write(struct foo_priv *foo, void *data)
> {
> @@ -707,3 +709,366 @@ pm_runtime_autosuspend_expiration() from within the ->runtime_suspend()
> callback while holding its private lock. If the function returns a nonzero
> value then the delay has not yet expired and the callback should return
> -EAGAIN.
> +
> +.. _Section 10:
> +
> +10. Example Driver Patterns
> +===========================
> +
> +The runtime PM API is large and complex, but most device drivers follow a small
> +set of canonical patterns when interacting with runtime PM. This section
> +illustrates standard patterns for device probing, performing I/O, and handling
> +interrupts.
> +
> +Probe and Initialization
> +------------------------
> +
> +Basic Probe
> +~~~~~~~~~~~
> +
> +A driver that powers on its hardware during probe and does not use autosuspend
> +can initialize runtime PM using device-managed helpers:
> +
> +.. code-block:: c
> +
> + static int foo_probe(struct platform_device *pdev)
> + {
> + struct device *dev = &pdev->dev;
> + struct foo_priv *priv;
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + /* Power on and initialize hardware registers... */
> +
> + /*
> + * The code above left hardware powered on and operational, so
> + * tell the PM core that the device is active before enabling
> + * runtime PM.
> + */
> + pm_runtime_set_active(dev);
> +
> + ret = devm_pm_runtime_enable(dev);
> + if (ret)
> + return ret;
> +
> + /*
> + * Alternatively, the above two calls can be combined into:
> + * ret = devm_pm_runtime_set_active_enabled(dev);
> + * if (ret)
> + * return ret;
> + */
> +
> + /*
> + * Upon successful return from ->probe(), the driver core
> + * automatically executes pm_request_idle(dev), allowing the
> + * device to suspend asynchronously if its usage counter is zero.
> + */
> + return 0;
The above looks nice and simple, but what happens in the error path is
equally important.
In principle, nothing prevents the runtime PM callbacks to be invoked
until pm_runtime_disable() has been called at some point *after* the
probe callback has returned. This needs to be taken care of correctly.
Likewise, as it's great with an example for ->probe(), it would be
nice with a corresponding example for ->remove().
I will have to defer reviewing the remaining parts in the $subject
patch, a bit limited bandwidth at the moment.
[...]
Kind regards
Uffe