On 10/22/25 8:50 PM, Mario Limonciello wrote:
> From: "Mario Limonciello (AMD)" <[email protected]>
>
> During a normal successful hibernate sequence devices will go through
> the freeze() callbacks create an image, go through the thaw() callbacks,
> and poweroff() callbacks.
>
> During a successful hibernate sequence some device drivers may want to
> skip the thaw() callbacks. This confuses the PM core though because it
> thinks the device is no longer suspended.
>
> To accommodate drivers that want to do this, introduce a new is_frozen
> bit that the driver can set and manage. From the driver perspective
> any thaw() or restore() callbacks that are being skipped should set
> is_frozen and return an error code. The PM core will then put the
> device back into the list of devices to resume for any aborted hibernate.
>
> Cc: Muhammad Usama Anjum <[email protected]>
> Signed-off-by: Mario Limonciello (AMD) <[email protected]>
Tested-by: Muhammad Usama Anjum <[email protected]>
> ---
> Documentation/driver-api/pm/devices.rst | 8 ++++++++
> drivers/base/power/main.c | 5 +++++
> include/linux/pm.h | 3 +++
> 3 files changed, 16 insertions(+)
>
> diff --git a/Documentation/driver-api/pm/devices.rst
> b/Documentation/driver-api/pm/devices.rst
> index 36d5c9c9fd11..55c633727108 100644
> --- a/Documentation/driver-api/pm/devices.rst
> +++ b/Documentation/driver-api/pm/devices.rst
> @@ -578,6 +578,14 @@ should already have been stored during the ``freeze``,
> ``freeze_late`` or
> the entire system, so it is not necessary for the callback to put the device
> in
> a low-power state.
>
> +Skipping thaw phase
> +-------------------
> +In some rare situations, it may be desirable to skip the thaw phases
> +(``thaw_noirq``, ``thaw_early``, ``thaw``) of a device entirely. This can be
> +achieved by a device driver returning an error code from any of it's thaw
> +callbacks but also setting dev->power.is_frozen to true. This indicates to
> the
> +PM core that the device is still in the frozen state. The PM core will
> consider
> +this when resuming the device in later phases such as `restore` or
> `poweroff`.
>
> Leaving Hibernation
> -------------------
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index e83503bdc1fd..451d54486645 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -1100,6 +1100,11 @@ static void device_resume(struct device *dev,
> pm_message_t state, bool async)
>
> End:
> error = dpm_run_callback(callback, dev, state, info);
> + /* device manages frozen state */
> + if (error && dev->power.is_frozen) {
> + dev->power.is_suspended = true;
> + error = 0;
> + }
>
> device_unlock(dev);
> dpm_watchdog_clear(&wd);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index cc7b2dc28574..52ee38d72aa2 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -688,6 +688,9 @@ struct dev_pm_info {
> #else
> bool should_wakeup:1;
> #endif
> +#ifdef CONFIG_HIBERNATE_CALLBACKS
> + bool is_frozen:1; /* Owned by the driver */
> +#endif
> #ifdef CONFIG_PM
> struct hrtimer suspend_timer;
> u64 timer_expires;
--
---
Thanks,
Usama