[PATCH] ACPI: x86: s2idle: Invoke Microsoft _DSM Function 9 (Turn On Display)

Jakob Riemenschneider posted 1 patch 1 month ago
There is a newer version of this series
drivers/acpi/x86/s2idle.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
[PATCH] ACPI: x86: s2idle: Invoke Microsoft _DSM Function 9 (Turn On Display)
Posted by Jakob Riemenschneider 1 month ago
Windows 11, version 22H2 introduced a new function index (Function 9) to
the Microsoft LPS0 _DSM, titled "Turn On Display Notification".

According to Microsoft documentation, this function signals to the system
firmware that the OS intends to turn on the display when exiting Modern
Standby. This allows the firmware to release Power Limits (PLx) earlier,
improving resume latency on supported OEM designs. Without this call,
some devices may remain in a throttled power state longer than necessary
during resume.

This patch defines the new function index (ACPI_LPS0_MS_DISPLAY_ON) and
invokes it in acpi_s2idle_restore_early_lps0() immediately after the
screen-on notification, provided the firmware supports the function in
its mask.

Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications#turn-on-display-notification-function-9
Link: https://bugzilla.kernel.org/show_bug.cgi?id=220505
Signed-off-by: Jakob Riemenschneider <jriemenschne@student.ethz.ch>
---
 drivers/acpi/x86/s2idle.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index 6d4d06236..4ce4cc8a0 100644
--- a/drivers/acpi/x86/s2idle.c
+++ b/drivers/acpi/x86/s2idle.c
@@ -45,6 +45,7 @@ static const struct acpi_device_id lps0_device_ids[] = {
 #define ACPI_LPS0_EXIT		6
 #define ACPI_LPS0_MS_ENTRY      7
 #define ACPI_LPS0_MS_EXIT       8
+#define ACPI_LPS0_MS_DISPLAY_ON 9
 
 /* AMD */
 #define ACPI_LPS0_DSM_UUID_AMD      "e3f32452-febc-43ce-9039-932122d37721"
@@ -352,6 +353,8 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
 			return "lps0 ms entry";
 		case ACPI_LPS0_MS_EXIT:
 			return "lps0 ms exit";
+		case ACPI_LPS0_MS_DISPLAY_ON:
+			return "lps0 ms display on";
 		}
 	} else {
 		switch (state) {
@@ -618,9 +621,14 @@ static void acpi_s2idle_restore_early_lps0(void)
 	}
 
 	/* Screen on */
-	if (lps0_dsm_func_mask_microsoft > 0)
+	if (lps0_dsm_func_mask_microsoft > 0) {
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+				/* Modern Turn Display On */
+		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_DISPLAY_ON,
+				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+	}
+
 	if (lps0_dsm_func_mask > 0)
 		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
 					ACPI_LPS0_SCREEN_ON_AMD :
-- 
2.52.0
Re: [PATCH] ACPI: x86: s2idle: Invoke Microsoft _DSM Function 9 (Turn On Display)
Posted by Rafael J. Wysocki 1 week, 3 days ago
On Wed, Jan 7, 2026 at 4:40 PM Jakob Riemenschneider
<riemenschneiderjakob@gmail.com> wrote:
>
> Windows 11, version 22H2 introduced a new function index (Function 9) to
> the Microsoft LPS0 _DSM, titled "Turn On Display Notification".
>
> According to Microsoft documentation, this function signals to the system
> firmware that the OS intends to turn on the display when exiting Modern
> Standby. This allows the firmware to release Power Limits (PLx) earlier,
> improving resume latency on supported OEM designs. Without this call,
> some devices may remain in a throttled power state longer than necessary
> during resume.

Has this been observed in the field?

Any examples?

> This patch defines the new function index (ACPI_LPS0_MS_DISPLAY_ON) and
> invokes it in acpi_s2idle_restore_early_lps0() immediately after the
> screen-on notification, provided the firmware supports the function in
> its mask.
>
> Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-firmware-notifications#turn-on-display-notification-function-9
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=220505
> Signed-off-by: Jakob Riemenschneider <jriemenschne@student.ethz.ch>
> ---
>  drivers/acpi/x86/s2idle.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
> index 6d4d06236..4ce4cc8a0 100644
> --- a/drivers/acpi/x86/s2idle.c
> +++ b/drivers/acpi/x86/s2idle.c
> @@ -45,6 +45,7 @@ static const struct acpi_device_id lps0_device_ids[] = {
>  #define ACPI_LPS0_EXIT         6
>  #define ACPI_LPS0_MS_ENTRY      7
>  #define ACPI_LPS0_MS_EXIT       8
> +#define ACPI_LPS0_MS_DISPLAY_ON 9
>
>  /* AMD */
>  #define ACPI_LPS0_DSM_UUID_AMD      "e3f32452-febc-43ce-9039-932122d37721"
> @@ -352,6 +353,8 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
>                         return "lps0 ms entry";
>                 case ACPI_LPS0_MS_EXIT:
>                         return "lps0 ms exit";
> +               case ACPI_LPS0_MS_DISPLAY_ON:
> +                       return "lps0 ms display on";
>                 }
>         } else {
>                 switch (state) {
> @@ -618,9 +621,14 @@ static void acpi_s2idle_restore_early_lps0(void)
>         }
>
>         /* Screen on */
> -       if (lps0_dsm_func_mask_microsoft > 0)
> +       if (lps0_dsm_func_mask_microsoft > 0) {
>                 acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
>                                 lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
> +                               /* Modern Turn Display On */
> +               acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_DISPLAY_ON,
> +                               lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);

Is the ordering right with respect to the non-MSFT screen-on
notifications below?

I would expect it to be done after all of the screen-on notifications,
so is there a specific reason to do it earlier?

> +       }
> +
>         if (lps0_dsm_func_mask > 0)
>                 acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
>                                         ACPI_LPS0_SCREEN_ON_AMD :
> --

Also, this kind of clashes with the "dark mode" work in progress, see
for example:

https://lore.kernel.org/linux-acpi/20251226102656.6296-1-lkml@antheas.dev/