diff mbox series

[RFC,03/13] acpi/x86: s2idle: add support for Sleep Entry and Sleep Exit callbacks

Message ID 20241121172239.119590-4-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 Sleep Entry and Sleep Exit firmware notifications allow the platform
to enter Modern Standby. In this state, if supported, the platform turns
off auxiliary USB devices (e.g., the controllers of the Legion Go),
makes the power light of the device flash, and lowers the power envelope
to a minimum that still allows for software activity without affecting
battery life.

Allow for entering this state prior to initiating the suspend sequence.
This fixes issues where the EC or the USB of the device need time to
power down before entering the suspend sequence, and allows for entering
this power state without suspending the device.

Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
 include/linux/suspend.h |  2 ++
 kernel/power/suspend.c  | 10 ++++++++++
 2 files changed, 12 insertions(+)
diff mbox series

Patch

diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 57c083754e8b..733dffb09b28 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -133,6 +133,7 @@  struct platform_suspend_ops {
 
 struct platform_s2idle_ops {
 	int (*display_off)(void);
+	int (*sleep_entry)(void);
 	int (*begin)(void);
 	int (*prepare)(void);
 	int (*prepare_late)(void);
@@ -141,6 +142,7 @@  struct platform_s2idle_ops {
 	void (*restore_early)(void);
 	void (*restore)(void);
 	void (*end)(void);
+	int (*sleep_exit)(void);
 	int (*display_on)(void);
 };
 
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index cded6b9b439b..3f4bbefa9b82 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -259,6 +259,16 @@  static int platform_standby_display_off(void)
 	return s2idle_ops && s2idle_ops->display_off ? s2idle_ops->display_off() : 0;
 }
 
+static int platform_standby_sleep_entry(void)
+{
+	return s2idle_ops && s2idle_ops->sleep_entry ? s2idle_ops->sleep_entry() : 0;
+}
+
+static int platform_standby_sleep_exit(void)
+{
+	return s2idle_ops && s2idle_ops->sleep_exit ? s2idle_ops->sleep_exit() : 0;
+}
+
 static int platform_standby_display_on(void)
 {
 	return s2idle_ops && s2idle_ops->display_on ? s2idle_ops->display_on() : 0;