diff mbox series

[RFC,10/13] acpi/x86: s2idle: add Turn On Display and call as part of callback

Message ID 20241121172239.119590-11-lkml@antheas.dev
State New
Headers show
Series acpi/x86: s2idle: implement Modern Standby transition states and expose to userspace | expand

Commit Message

Antheas Kapenekakis Nov. 21, 2024, 5:22 p.m. UTC
The Turn On Display callback was introduced in Windows 22H2, to allow
devices to resume faster from sleep. Essentially, if the device lowers
its power limit (PLx) while it is in the Sleep state, this might lengthen
the suspend sequence in an undesirable manner. Implement this callback,
which corresponds to Modern Standby Firmware notification (_DSM) 9.

Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
 drivers/acpi/x86/s2idle.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
diff mbox series

Patch

diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index bdc2cc8d4994..d389c57d2963 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_SLEEP_ENTRY      7
 #define ACPI_LPS0_SLEEP_EXIT       8
+#define ACPI_LPS0_TURN_ON_DISPLAY  9
 
 /* AMD */
 #define ACPI_LPS0_DSM_UUID_AMD      "e3f32452-febc-43ce-9039-932122d37721"
@@ -375,6 +376,8 @@  static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
 			return "sleep entry";
 		case ACPI_LPS0_SLEEP_EXIT:
 			return "sleep exit";
+		case ACPI_LPS0_TURN_ON_DISPLAY:
+			return "turn on display";
 		}
 	} else {
 		switch (state) {
@@ -589,6 +592,29 @@  static int acpi_s2idle_sleep_entry(void)
 	return 0;
 }
 
+static int acpi_s2idle_turn_on_display(void)
+{
+	if (!lps0_device_handle || sleep_no_lps0 ||
+	    lps0_dsm_func_mask_microsoft <= 0)
+		return 0;
+
+	/* This call is only valid while we are in a sleep state */
+	if (WARN_ON(!lsp0_dsm_in_sleep))
+		return -EINVAL;
+
+	acpi_scan_lock_acquire();
+
+	/* Modern Standby Turn On Display */
+	if (lps0_dsm_func_mask_microsoft > 0)
+		acpi_sleep_run_lps0_dsm(ACPI_LPS0_TURN_ON_DISPLAY,
+					lps0_dsm_func_mask_microsoft,
+					lps0_dsm_guid_microsoft);
+
+	acpi_scan_lock_release();
+
+	return 0;
+}
+
 static int acpi_s2idle_sleep_exit(void)
 {
 	if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0)
@@ -714,6 +740,7 @@  static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
 	.restore_early = acpi_s2idle_restore_early,
 	.restore = acpi_s2idle_restore,
 	.end = acpi_s2idle_end,
+	.turn_on_display = acpi_s2idle_turn_on_display,
 	.sleep_exit = acpi_s2idle_sleep_exit,
 	.display_on = acpi_s2idle_display_on,
 };