public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Mario Limonciello <mario.limonciello@amd.com>
To: "Rafael J . Wysocki" <rjw@rjwysocki.net>, <linux-acpi@vger.kernel.org>
Cc: <Shyam-sundar.S-k@amd.com>,
	Basavaraj Natikar <Basavaraj.Natikar@amd.com>,
	Mario Limonciello <mario.limonciello@amd.com>
Subject: [PATCH 2/3] PM: sleep: Don't always assume s2idle will be enabled
Date: Wed, 5 Jan 2022 13:39:09 -0600	[thread overview]
Message-ID: <20220105193910.25678-3-mario.limonciello@amd.com> (raw)
In-Reply-To: <20220105193910.25678-1-mario.limonciello@amd.com>

Some platforms may require firmware support for s2idle to work
properly, so allow other drivers that set s2idle ops to decide whether
to offer it on a given platform.

This should be no functional change for any platform.

Reviewed-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
 drivers/acpi/sleep.c      |  6 ++++++
 drivers/acpi/x86/s2idle.c |  6 ++++++
 include/linux/suspend.h   |  1 +
 kernel/power/suspend.c    | 27 ++++++++++++++-------------
 4 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index eaa47753b758..9dafdaafa5dc 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -800,12 +800,18 @@ void acpi_s2idle_end(void)
 	acpi_scan_lock_release();
 }
 
+static bool acpi_s2idle_valid(void)
+{
+	return true;
+}
+
 static const struct platform_s2idle_ops acpi_s2idle_ops = {
 	.begin = acpi_s2idle_begin,
 	.prepare = acpi_s2idle_prepare,
 	.wake = acpi_s2idle_wake,
 	.restore = acpi_s2idle_restore,
 	.end = acpi_s2idle_end,
+	.valid = acpi_s2idle_valid,
 };
 
 void __weak acpi_s2idle_setup(void)
diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
index 32ab4ba5adb9..a1626737e5e0 100644
--- a/drivers/acpi/x86/s2idle.c
+++ b/drivers/acpi/x86/s2idle.c
@@ -361,6 +361,11 @@ static int validate_dsm(acpi_handle handle, const char *uuid, int rev, guid_t *d
 	return ret;
 }
 
+static bool acpi_s2idle_valid(void)
+{
+	return true;
+}
+
 static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
 	.begin = acpi_s2idle_begin,
 	.prepare = acpi_s2idle_prepare,
@@ -369,6 +374,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,
+	.valid = acpi_s2idle_valid,
 };
 
 static int lps0_device_attach(struct acpi_device *adev,
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 8af13ba60c7e..51e5bdd9be23 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -195,6 +195,7 @@ struct platform_s2idle_ops {
 	void (*restore_early)(void);
 	void (*restore)(void);
 	void (*end)(void);
+	bool (*valid)(void);
 };
 
 #ifdef CONFIG_SUSPEND
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 597c5e65aa45..29d6f1738359 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -46,7 +46,7 @@ static const char * const mem_sleep_labels[] = {
 };
 const char *mem_sleep_states[PM_SUSPEND_MAX];
 
-suspend_state_t mem_sleep_current = PM_SUSPEND_TO_IDLE;
+suspend_state_t mem_sleep_current = PM_SUSPEND_MAX;
 suspend_state_t mem_sleep_default = PM_SUSPEND_MAX;
 suspend_state_t pm_suspend_target_state;
 EXPORT_SYMBOL_GPL(pm_suspend_target_state);
@@ -152,6 +152,10 @@ EXPORT_SYMBOL_GPL(s2idle_wake);
 
 static bool valid_state(suspend_state_t state)
 {
+	/* PM_SUSPEND_TO_IDLE may require low-level support on some platforms */
+	if (state == PM_SUSPEND_TO_IDLE)
+		return s2idle_ops && s2idle_ops->valid && s2idle_ops->valid();
+
 	/*
 	 * The PM_SUSPEND_STANDBY and PM_SUSPEND_MEM states require low-level
 	 * support and need to be valid to the low-level implementation.
@@ -166,6 +170,13 @@ void s2idle_set_ops(const struct platform_s2idle_ops *ops)
 {
 	lock_system_sleep();
 	s2idle_ops = ops;
+	if (valid_state(PM_SUSPEND_TO_IDLE)) {
+		mem_sleep_states[PM_SUSPEND_TO_IDLE] = mem_sleep_labels[PM_SUSPEND_TO_IDLE];
+		/* if supported, update to suspend to idle for default when ops set */
+		if (mem_sleep_current == PM_SUSPEND_MAX ||
+		    mem_sleep_default == PM_SUSPEND_TO_IDLE)
+			mem_sleep_current = PM_SUSPEND_TO_IDLE;
+	}
 	unlock_system_sleep();
 }
 
@@ -174,11 +185,6 @@ void __init pm_states_init(void)
 	/* "mem" and "freeze" are always present in /sys/power/state. */
 	pm_states[PM_SUSPEND_MEM] = pm_labels[PM_SUSPEND_MEM];
 	pm_states[PM_SUSPEND_TO_IDLE] = pm_labels[PM_SUSPEND_TO_IDLE];
-	/*
-	 * Suspend-to-idle should be supported even without any suspend_ops,
-	 * initialize mem_sleep_states[] accordingly here.
-	 */
-	mem_sleep_states[PM_SUSPEND_TO_IDLE] = mem_sleep_labels[PM_SUSPEND_TO_IDLE];
 }
 
 static int __init mem_sleep_default_setup(char *str)
@@ -236,11 +242,6 @@ int suspend_valid_only_mem(suspend_state_t state)
 }
 EXPORT_SYMBOL_GPL(suspend_valid_only_mem);
 
-static bool sleep_state_supported(suspend_state_t state)
-{
-	return state == PM_SUSPEND_TO_IDLE || valid_state(state);
-}
-
 static int platform_suspend_prepare(suspend_state_t state)
 {
 	return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ?
@@ -346,7 +347,7 @@ static int suspend_prepare(suspend_state_t state)
 {
 	int error;
 
-	if (!sleep_state_supported(state))
+	if (!valid_state(state))
 		return -EPERM;
 
 	pm_prepare_console();
@@ -478,7 +479,7 @@ int suspend_devices_and_enter(suspend_state_t state)
 	int error;
 	bool wakeup = false;
 
-	if (!sleep_state_supported(state))
+	if (!valid_state(state))
 		return -ENOSYS;
 
 	pm_suspend_target_state = state;
-- 
2.25.1


  parent reply	other threads:[~2022-01-05 19:39 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-05 19:39 [PATCH 0/3] On AMD platforms only offer s2idle w/ proper FW Mario Limonciello
2022-01-05 19:39 ` [PATCH 1/3] PM: suspend: Move some structure declarations around Mario Limonciello
2022-01-05 19:39 ` Mario Limonciello [this message]
2022-01-05 19:39 ` [PATCH 3/3] acpi: sleep: Don't offer s2idle on AMD platforms without LPS0 Mario Limonciello
2022-01-11 15:52 ` [PATCH 0/3] On AMD platforms only offer s2idle w/ proper FW Rafael J. Wysocki
2022-01-11 16:23   ` Limonciello, Mario
2022-01-11 17:05     ` Rafael J. Wysocki
2022-01-11 17:32       ` Limonciello, Mario
2022-01-11 17:32       ` Deucher, Alexander
2022-01-11 17:44         ` Rafael J. Wysocki
2022-01-11 18:30           ` Deucher, Alexander
2022-01-11 18:36             ` Limonciello, Mario
2022-01-11 19:20               ` Rafael J. Wysocki
2022-01-11 19:35                 ` Limonciello, Mario
2022-01-11 19:48                   ` Rafael J. Wysocki

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=20220105193910.25678-3-mario.limonciello@amd.com \
    --to=mario.limonciello@amd.com \
    --cc=Basavaraj.Natikar@amd.com \
    --cc=Shyam-sundar.S-k@amd.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    /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