On Fri, Dec 26, 2025 at 11:27 AM Antheas Kapenekakis <[email protected]> wrote:
>
> Implement the standby states as part of hibernation. Specifically,
> ensure we are in the inactive state before hibernation entry, and
> sync the state as active after hibernation resume. In case of a failed
> hibernation, restore the previous standby state.

We've not mixed up "modern standby" _DSM calls with hibernation so
far, so this change is potentially risky.

> Signed-off-by: Antheas Kapenekakis <[email protected]>
> ---
>  kernel/power/hibernate.c | 29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index af8d07bafe02..85a5ca8f6537 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -787,7 +787,11 @@ static int load_image_and_restore(void)
>   */
>  int hibernate(void)
>  {
> +#ifdef CONFIG_SUSPEND
> +       standby_state_t previous_standby;
> +#endif
>         bool snapshot_test = false;
> +       bool powered_down = false;
>         unsigned int sleep_flags;
>         int error;
>
> @@ -815,6 +819,13 @@ int hibernate(void)
>         }
>
>         pr_info("hibernation entry\n");
> +
> +#if CONFIG_SUSPEND
> +       /* Enter the standby screen off state in case userspace has not. */
> +       previous_standby = pm_standby_get_state();
> +       pm_standby_transition(PM_STANDBY_INACTIVE);
> +#endif
> +
>         pm_prepare_console();
>         error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, 
> PM_POST_HIBERNATION);
>         if (error)
> @@ -867,10 +878,12 @@ int hibernate(void)
>                 error = swsusp_write(flags);
>                 swsusp_free();
>                 if (!error) {
> -                       if (hibernation_mode == HIBERNATION_TEST_RESUME)
> +                       if (hibernation_mode == HIBERNATION_TEST_RESUME) {
>                                 snapshot_test = true;
> -                       else
> +                       } else {
> +                               powered_down = true;
>                                 power_down();
> +                       }
>                 }
>                 in_suspend = 0;
>                 pm_restore_gfp_mask();
> @@ -897,6 +910,18 @@ int hibernate(void)
>   Notify:
>         pm_notifier_call_chain(PM_POST_HIBERNATION);
>   Restore:
> +#if CONFIG_SUSPEND
> +       /*
> +        * If we resumed from S5, we are in the active standby state. However,
> +        * the kernel restored a stale value. Sync it. Otherwise, in e.g., the
> +        * case of a failed hibernation, transition to the previous value.
> +        */
> +       if (powered_down)
> +               pm_standby_set_state(PM_STANDBY_ACTIVE);
> +       else
> +               pm_standby_transition(previous_standby);
> +#endif
> +
>         pm_restore_console();
>         hibernate_release();
>   Unlock:
> --
> 2.52.0
>
>
>

Reply via email to