From: Antheas Kapenekakis <lkml@antheas.dev>
To: dmitry.osipenko@collabora.com
Cc: bob.beckett@collabora.com, bookeldor@gmail.com,
hadess@hadess.net, jaap@haitsma.org, kernel@collabora.com,
lennart@poettering.net, linux-acpi@vger.kernel.org,
linux-kernel@vger.kernel.org, lkml@antheas.dev, mccann@jhu.edu,
rafael@kernel.org, richard@hughsie.com,
sebastian.reichel@collabora.com, superm1@kernel.org,
systemd-devel@lists.freedesktop.org, xaver.hugl@gmail.com
Subject: [RFC v1 8/8] PM: standby: Add sysfs attribute for runtime standby transitions
Date: Fri, 26 Dec 2025 12:26:46 +0200 [thread overview]
Message-ID: <20251226102656.6296-9-lkml@antheas.dev> (raw)
In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev>
Add a sysfs attribute to allow informing the kernel about the current
standby state of the device depending on user involvement, those being:
"active", "inactive", "sleep", and "resume" (in "sleep" but preparing
for presenting to the user faster).
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
---
kernel/power/main.c | 84 ++++++++++++++++++++++++++++++++++++++++++++
kernel/power/power.h | 1 +
2 files changed, 85 insertions(+)
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 03b2c5495c77..30494be41557 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -830,6 +830,89 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
power_attr(state);
+#ifdef CONFIG_SUSPEND
+/*
+ * standby - control system s2idle standby state.
+ *
+ * show() returns available standby states, which may be "active", "screen_off",
+ * "sleep" and "resume" (still in sleep but preparing to present to user).
+ * See Documentation/admin-guide/pm/standby-states.rst for a description of
+ * what they mean.
+ *
+ * store() accepts one of those strings and initiates a transition to that
+ * standby state.
+ *
+ * For backwards compatibility, when the system suspends, it first enters the
+ * state "sleep", regardless of what was written into store() and then during
+ * resume restores the previous value.
+ */
+static ssize_t standby_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ unsigned int sleep_flags;
+ standby_state_t i, curr;
+ char *s = buf;
+
+ sleep_flags = lock_system_sleep();
+ pm_standby_refresh_states();
+ curr = pm_standby_get_state();
+ unlock_system_sleep(sleep_flags);
+
+ if (curr < 0)
+ return -EBUSY;
+
+ for (i = PM_STANDBY_MIN; i < PM_STANDBY_MAX; i++)
+ if (standby_states[i])
+ s += sprintf(s, curr == i ? "[%s] " : "%s ", standby_states[i]);
+
+ if (s != buf)
+ /* convert the last space to a newline */
+ *(s - 1) = '\n';
+ return (s - buf);
+}
+
+static standby_state_t decode_standby_state(const char *buf, size_t n)
+{
+ standby_state_t state;
+ char *p;
+ int len;
+
+ p = memchr(buf, '\n', n);
+ len = p ? p - buf : n;
+
+ for (state = PM_STANDBY_MIN; state < PM_STANDBY_MAX; state++) {
+ const char *label = standby_states[state];
+
+ if (label && len == strlen(label) && !strncmp(buf, label, len))
+ return state;
+ }
+
+ return PM_STANDBY_MAX;
+}
+
+static ssize_t standby_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int sleep_flags;
+ standby_state_t state;
+ int error;
+
+ sleep_flags = lock_system_sleep();
+ pm_standby_refresh_states();
+ state = decode_standby_state(buf, n);
+
+ if (state >= PM_STANDBY_MAX)
+ return -EINVAL;
+
+ error = pm_standby_transition(state);
+ unlock_system_sleep(sleep_flags);
+
+ return error ? error : n;
+}
+
+power_attr(standby);
+#endif
+
#ifdef CONFIG_PM_SLEEP
/*
* The 'wakeup_count' attribute, along with the functions defined in
@@ -1084,6 +1167,7 @@ static struct attribute * g[] = {
#ifdef CONFIG_SUSPEND
&mem_sleep_attr.attr,
&sync_on_suspend_attr.attr,
+ &standby_attr.attr,
#endif
#ifdef CONFIG_PM_AUTOSLEEP
&autosleep_attr.attr,
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 75b63843886e..2327a1ce2b05 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -216,6 +216,7 @@ extern void swsusp_show_speed(ktime_t, ktime_t, unsigned int, char *);
extern const char * const pm_labels[];
extern const char *pm_states[];
extern const char *mem_sleep_states[];
+extern const char *standby_states[];
extern int suspend_devices_and_enter(suspend_state_t state);
#else /* !CONFIG_SUSPEND */
--
2.52.0
next prev parent reply other threads:[~2025-12-26 10:27 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-26 10:26 [RFC v1 0/8] acpi/x86: s2idle: Introduce and implement runtime standby ABI for ACPI s0ix platforms Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 1/8] Documentation: PM: Add documentation for Runtime Standby States Antheas Kapenekakis
2026-03-13 20:07 ` Rafael J. Wysocki
2026-03-16 19:54 ` Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 2/8] acpi/x86: s2idle: Rename LPS0 constants so they mirror their function Antheas Kapenekakis
2026-03-13 20:12 ` Rafael J. Wysocki
2026-03-16 20:01 ` Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 3/8] acpi/x86: s2idle: add runtime standby transition function Antheas Kapenekakis
2025-12-27 7:25 ` kernel test robot
2026-03-13 20:29 ` Rafael J. Wysocki
2026-03-16 20:06 ` Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 4/8] acpi/x86: s2idle: add support for querying runtime standby state support Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 5/8] acpi/x86: s2idle: move DSM notifications to do_notification callback Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 6/8] acpi/x86: s2idle: implement turn on display DSM as resume notification Antheas Kapenekakis
2025-12-26 10:26 ` [RFC v1 7/8] PM: hibernate: Enter s2idle sleep state before hibernation Antheas Kapenekakis
2025-12-27 11:39 ` kernel test robot
2026-03-13 20:33 ` Rafael J. Wysocki
2026-03-16 20:09 ` Antheas Kapenekakis
2025-12-26 10:26 ` Antheas Kapenekakis [this message]
2026-01-12 20:33 ` [RFC v1 0/8] acpi/x86: s2idle: Introduce and implement runtime standby ABI for ACPI s0ix platforms Antheas Kapenekakis
2026-01-13 9:48 ` Dmitry Osipenko
2026-01-13 10:11 ` Antheas Kapenekakis
2026-01-14 23:07 ` Dmitry Osipenko
2026-01-15 7:49 ` Antheas Kapenekakis
2026-03-16 19:02 ` Dmitry Osipenko
2026-03-16 19:33 ` Antheas Kapenekakis
2026-03-16 19:36 ` Antheas Kapenekakis
2026-03-17 11:04 ` Dmitry Osipenko
2026-04-22 0:56 ` Dmitry Osipenko
2026-04-22 8:51 ` Antheas Kapenekakis
2026-04-22 8:58 ` Antheas Kapenekakis
2026-04-24 1:35 ` Dmitry Osipenko
2026-04-24 13:48 ` Mario Limonciello
2026-04-24 16:13 ` Antheas Kapenekakis
2026-02-27 14:59 ` Antheas Kapenekakis
2026-02-27 18:42 ` Rafael J. Wysocki
2026-03-13 19:36 ` Rafael J. Wysocki
2026-03-16 19:52 ` Antheas Kapenekakis
2026-03-17 11:56 ` Dmitry Osipenko
2026-03-17 12:09 ` Rafael J. Wysocki
2026-03-17 15:13 ` Mario Limonciello
2026-03-19 12:35 ` Antheas Kapenekakis
2026-03-20 20:41 ` Mario Limonciello (AMD) (kernel.org)
2026-03-21 13:46 ` Antheas Kapenekakis
2026-03-21 13:52 ` Antheas Kapenekakis
2026-03-21 18:43 ` Mario Limonciello
2026-03-21 22:33 ` Antheas Kapenekakis
2026-03-23 4:36 ` Mario Limonciello
2026-03-23 9:26 ` Antheas Kapenekakis
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=20251226102656.6296-9-lkml@antheas.dev \
--to=lkml@antheas.dev \
--cc=bob.beckett@collabora.com \
--cc=bookeldor@gmail.com \
--cc=dmitry.osipenko@collabora.com \
--cc=hadess@hadess.net \
--cc=jaap@haitsma.org \
--cc=kernel@collabora.com \
--cc=lennart@poettering.net \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mccann@jhu.edu \
--cc=rafael@kernel.org \
--cc=richard@hughsie.com \
--cc=sebastian.reichel@collabora.com \
--cc=superm1@kernel.org \
--cc=systemd-devel@lists.freedesktop.org \
--cc=xaver.hugl@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.