From: Mario Limonciello <mario.limonciello@amd.com>
To: <rafael@kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <linux-pm@vger.kernel.org>, <Shyam-sundar.S-k@amd.com>,
Mario Limonciello <mario.limonciello@amd.com>,
Len Brown <lenb@kernel.org>, <linux-acpi@vger.kernel.org>
Subject: [PATCH] ACPI: x86: Separate out the Microsoft _DSM function calls
Date: Thu, 20 Apr 2023 11:09:23 -0500 [thread overview]
Message-ID: <20230420160923.14127-1-mario.limonciello@amd.com> (raw)
When utilizing the Microsoft _DSM there are six calls which correspond
to the following states:
1) Idle (Screen on)
2) Idle (Screen off)
3) Low Power
4) Modern Standby
Currently Linux compresses these and treats this as two states:
1) Awake
2) s2idle
That is when the system has woken from s2idle from a pure ACPI event
the _DSM state is still Modern Standby at this time, and so some
firmware will not run other code that communicates with the EC.
To fix this, track the active state in the s2idle code and ensure that
"Modern Standby enter" is called after the ACPI SCI has been processed
from `acpi_s2idle_wake` and every time that the system is woken up call
"Modern Standby exit".
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
drivers/acpi/x86/s2idle.c | 85 +++++++++++++++++++++++++++++++--------
1 file changed, 69 insertions(+), 16 deletions(-)
diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index e499c60c4579..1772d981c5e9 100644
--- a/drivers/acpi/x86/s2idle.c
+++ b/drivers/acpi/x86/s2idle.c
@@ -59,6 +59,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;
/* Device constraint entry structure */
struct lpi_device_info {
@@ -320,6 +321,44 @@ static void lpi_check_constraints(void)
}
}
+static bool acpi_s2idle_vendor_amd(void)
+{
+ return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
+}
+
+static const char *acpi_sleep_dsm_state_to_str(unsigned int state)
+{
+ if (lps0_dsm_func_mask_microsoft || !acpi_s2idle_vendor_amd()) {
+ switch (state) {
+ case ACPI_LPS0_SCREEN_OFF:
+ return "screen off";
+ case ACPI_LPS0_SCREEN_ON:
+ return "screen on";
+ case ACPI_LPS0_ENTRY:
+ return "lps0 entry";
+ case ACPI_LPS0_EXIT:
+ return "lps0 exit";
+ case ACPI_LPS0_MS_ENTRY:
+ return "lps0 ms entry";
+ case ACPI_LPS0_MS_EXIT:
+ return "lps0 ms exit";
+ };
+ } else {
+ switch (state) {
+ case ACPI_LPS0_SCREEN_ON_AMD:
+ return "screen on";
+ case ACPI_LPS0_SCREEN_OFF_AMD:
+ return "screen off";
+ case ACPI_LPS0_ENTRY_AMD:
+ return "lps0 entry";
+ case ACPI_LPS0_EXIT_AMD:
+ return "lps0 exit";
+ }
+ }
+
+ return "unknown";
+}
+
static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, guid_t dsm_guid)
{
union acpi_object *out_obj;
@@ -331,13 +370,13 @@ static void acpi_sleep_run_lps0_dsm(unsigned int func, unsigned int func_mask, g
rev_id, func, NULL);
ACPI_FREE(out_obj);
- acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n",
- func, out_obj ? "successful" : "failed");
-}
-
-static bool acpi_s2idle_vendor_amd(void)
-{
- return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
+ lps0_dsm_state = func;
+ if (pm_debug_messages_on) {
+ acpi_handle_info(lps0_device_handle,
+ "%s transitioned to state %s\n",
+ out_obj ? "Successfully" : "Failed to",
+ acpi_sleep_dsm_state_to_str(lps0_dsm_state));
+ }
}
static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *dsm_guid)
@@ -487,9 +526,6 @@ int acpi_s2idle_prepare_late(void)
if (lps0_dsm_func_mask_microsoft > 0) {
acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
- /* modern standby entry */
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
}
list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
@@ -513,6 +549,28 @@ void acpi_s2idle_check(void)
}
}
+bool lps0_s2idle_wake(void)
+{
+ if (!lps0_device_handle || sleep_no_lps0)
+ goto out;
+
+ /* avoid running on the first go through the s2idle loop */
+ if (lps0_dsm_func_mask_microsoft > 0) {
+ int target;
+
+ if (lps0_dsm_state == ACPI_LPS0_ENTRY ||
+ lps0_dsm_state == ACPI_LPS0_MS_EXIT)
+ target = ACPI_LPS0_MS_ENTRY;
+ else
+ target = ACPI_LPS0_MS_EXIT;
+ acpi_sleep_run_lps0_dsm(target,
+ lps0_dsm_func_mask_microsoft,
+ lps0_dsm_guid_microsoft);
+ }
+out:
+ return acpi_s2idle_wake();
+}
+
void acpi_s2idle_restore_early(void)
{
struct acpi_s2idle_dev_ops *handler;
@@ -524,11 +582,6 @@ void acpi_s2idle_restore_early(void)
if (handler->restore)
handler->restore();
- /* Modern standby exit */
- if (lps0_dsm_func_mask_microsoft > 0)
- acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-
/* LPS0 exit */
if (lps0_dsm_func_mask > 0)
acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
@@ -555,7 +608,7 @@ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
.prepare = acpi_s2idle_prepare,
.prepare_late = acpi_s2idle_prepare_late,
.check = acpi_s2idle_check,
- .wake = acpi_s2idle_wake,
+ .wake = lps0_s2idle_wake,
.restore_early = acpi_s2idle_restore_early,
.restore = acpi_s2idle_restore,
.end = acpi_s2idle_end,
base-commit: 7124d7671af0facf115d70f9d1fadde0d768d325
--
2.34.1
next reply other threads:[~2023-04-20 16:10 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-20 16:09 Mario Limonciello [this message]
2023-04-21 6:15 ` kernel test robot
2023-04-24 12:20 ` kernel test robot
2023-04-24 15:13 ` kernel test robot
2023-04-24 22:22 ` Limonciello, Mario
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=20230420160923.14127-1-mario.limonciello@amd.com \
--to=mario.limonciello@amd.com \
--cc=Shyam-sundar.S-k@amd.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael@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
all inboxes | Powered by JetHome®