Linux Power Management development
 help / color / mirror / Atom feed
From: Antheas Kapenekakis <lkml@antheas.dev>
To: linux-pm@vger.kernel.org
Cc: platform-driver-x86@vger.kernel.org, Mario.Limonciello@amd.com,
	luke@ljones.dev, me@kylegospodneti.ch
Subject: [PATCH v1 3/4] acpi/x86: s2idle: call screen on and off as part of callbacks
Date: Thu, 19 Sep 2024 19:19:51 +0200	[thread overview]
Message-ID: <20240919171952.403745-4-lkml@antheas.dev> (raw)
In-Reply-To: <20240919171952.403745-1-lkml@antheas.dev>

Move the screen on and off calls into dedicated callbacks that gate
the ACPI mutex, so they can be called outside of the suspend path.
This fixes issues on certain devices that expect kernel drivers to be
fully active during the calls, and allows for the flexibility of calling
them as part of a more elaborate userspace suspend sequence (such as
with "Screen Off" in Windows Modern Standby).

Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
 drivers/acpi/x86/s2idle.c | 72 +++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 15 deletions(-)

diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index dd0b40b9bbe8..aa448ed58077 100644
--- a/drivers/acpi/x86/s2idle.c
+++ b/drivers/acpi/x86/s2idle.c
@@ -60,6 +60,7 @@ static int lps0_dsm_func_mask;
 static guid_t lps0_dsm_guid_microsoft;
 static int lps0_dsm_func_mask_microsoft;
 static int lps0_dsm_state;
+static bool lsp0_dsm_in_screen_off;
 
 /* Device constraint entry structure */
 struct lpi_device_info {
@@ -539,15 +540,19 @@ static struct acpi_scan_handler lps0_handler = {
 	.attach = lps0_device_attach,
 };
 
-int acpi_s2idle_prepare_late(void)
+static int acpi_s2idle_screen_off(void)
 {
-	struct acpi_s2idle_dev_ops *handler;
-
 	if (!lps0_device_handle || sleep_no_lps0)
 		return 0;
 
-	if (pm_debug_messages_on)
-		lpi_check_constraints();
+	if (lsp0_dsm_in_screen_off) {
+		acpi_handle_info(lps0_device_handle,
+				"called screen off call twice before calling screen on.\n");
+		// fallthrough for debugging, calling twice should be gated by the caller
+	}
+
+	lsp0_dsm_in_screen_off = true;
+	acpi_scan_lock_acquire();
 
 	/* Screen off */
 	if (lps0_dsm_func_mask > 0)
@@ -560,6 +565,50 @@ int acpi_s2idle_prepare_late(void)
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
 
+	acpi_scan_lock_release();
+
+	return 0;
+}
+
+static int acpi_s2idle_screen_on(void)
+{
+	if (!lps0_device_handle || sleep_no_lps0)
+		return 0;
+
+	if (!lsp0_dsm_in_screen_off) {
+		acpi_handle_info(lps0_device_handle,
+				"called screen on before calling screen off.\n");
+		// fallthrough for debugging, calling twice should be gated by the caller
+	}
+
+	lsp0_dsm_in_screen_off = false;
+	acpi_scan_lock_acquire();
+
+	/* Screen on */
+	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);
+	if (lps0_dsm_func_mask > 0)
+		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
+					ACPI_LPS0_SCREEN_ON_AMD :
+					ACPI_LPS0_SCREEN_ON,
+					lps0_dsm_func_mask, lps0_dsm_guid);
+
+	acpi_scan_lock_release();
+
+	return 0;
+}
+
+int acpi_s2idle_prepare_late(void)
+{
+	struct acpi_s2idle_dev_ops *handler;
+
+	if (!lps0_device_handle || sleep_no_lps0)
+		return 0;
+
+	if (pm_debug_messages_on)
+		lpi_check_constraints();
+
 	/* LPS0 entry */
 	if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd())
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
@@ -623,19 +672,10 @@ void acpi_s2idle_restore_early(void)
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
 	}
-
-	/* Screen on */
-	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);
-	if (lps0_dsm_func_mask > 0)
-		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-					ACPI_LPS0_SCREEN_ON_AMD :
-					ACPI_LPS0_SCREEN_ON,
-					lps0_dsm_func_mask, lps0_dsm_guid);
 }
 
 static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
+	.screen_off = acpi_s2idle_screen_off,
 	.begin = acpi_s2idle_begin,
 	.prepare = acpi_s2idle_prepare,
 	.prepare_late = acpi_s2idle_prepare_late,
@@ -644,10 +684,12 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
 	.restore_early = acpi_s2idle_restore_early,
 	.restore = acpi_s2idle_restore,
 	.end = acpi_s2idle_end,
+	.screen_on = acpi_s2idle_screen_on,
 };
 
 void __init acpi_s2idle_setup(void)
 {
+	lsp0_dsm_in_screen_off = false;
 	acpi_scan_add_handler(&lps0_handler);
 	s2idle_set_ops(&acpi_s2idle_ops_lps0);
 }
-- 
2.46.1


  parent reply	other threads:[~2024-09-19 17:20 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-19 17:19 [PATCH v1 0/4] acpi/x86: s2idle: move Display off/on calls outside suspend (fixes ROG Ally suspend) Antheas Kapenekakis
2024-09-19 17:19 ` [PATCH v1 1/4] acpi/x86: s2idle: add support for screen off and screen on callbacks Antheas Kapenekakis
2024-09-19 17:29   ` Mario Limonciello
2024-09-19 17:36     ` Antheas Kapenekakis
2024-09-19 20:17       ` Mario Limonciello
2024-09-19 17:19 ` [PATCH v1 2/4] acpi/x86: s2idle: handle screen off/on calls outside of suspend sequence Antheas Kapenekakis
2024-09-19 17:35   ` Mario Limonciello
2024-09-19 18:21     ` Alex Deucher
2024-09-19 18:32       ` Mario Limonciello
2024-09-19 18:35         ` Antheas Kapenekakis
2024-09-19 17:19 ` Antheas Kapenekakis [this message]
2024-09-19 19:01   ` [PATCH v1 3/4] acpi/x86: s2idle: call screen on and off as part of callbacks Mario Limonciello
2024-09-19 20:45     ` Antheas Kapenekakis
2024-09-19 20:51       ` Mario Limonciello
2024-09-19 20:54         ` Antheas Kapenekakis
2024-09-21  1:03           ` Denis Benato
2024-09-21  6:22             ` Antheas Kapenekakis
2024-09-21 14:47               ` Denis Benato
2024-09-21 19:44                 ` Antheas Kapenekakis
2024-09-22  2:07                   ` Denis Benato
2024-09-22  7:48                     ` Antheas Kapenekakis
2024-09-19 17:19 ` [PATCH v1 4/4] platform/x86: asus-wmi: remove Ally (1st gen) and Ally X suspend quirk Antheas Kapenekakis
2024-09-19 18:36   ` Mario Limonciello

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240919171952.403745-4-lkml@antheas.dev \
    --to=lkml@antheas.dev \
    --cc=Mario.Limonciello@amd.com \
    --cc=linux-pm@vger.kernel.org \
    --cc=luke@ljones.dev \
    --cc=me@kylegospodneti.ch \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox