Linux Power Management development
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Antheas Kapenekakis <lkml@antheas.dev>
Cc: linux-pm@vger.kernel.org, platform-driver-x86@vger.kernel.org,
	 dri-devel@lists.freedesktop.org,
	 Mario Limonciello <mario.limonciello@amd.com>,
	 Hans de Goede <hdegoede@redhat.com>,
	 Kyle Gospodnetich <me@kylegospodneti.ch>
Subject: Re: [RFC 13/13] PM: standby: Add sysfs attribute for modern standby transitions
Date: Thu, 28 Nov 2024 13:45:07 +0200 (EET)	[thread overview]
Message-ID: <ae43443d-74a8-799d-26aa-608af973a9e8@linux.intel.com> (raw)
In-Reply-To: <20241121172239.119590-14-lkml@antheas.dev>

On Thu, 21 Nov 2024, Antheas Kapenekakis wrote:

> Add a sysfs attribute to allow informing the kernel about the current
> standby state, those being: "active", "screen_off", "sleep", and
> "resume" (to prepare turning the display on). The final modern
> standby state DRIPS is omitted, as that is entered during the kernel
> suspend process and userspace will never see it.
> 
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
>  Documentation/ABI/testing/sysfs-power | 34 ++++++++++++
>  kernel/power/main.c                   | 75 +++++++++++++++++++++++++++
>  2 files changed, 109 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power
> index a3942b1036e2..eff13980cc7c 100644
> --- a/Documentation/ABI/testing/sysfs-power
> +++ b/Documentation/ABI/testing/sysfs-power
> @@ -39,6 +39,40 @@ Description:
>  		See Documentation/admin-guide/pm/sleep-states.rst for more
>  		information.
>  
> +What:		/sys/power/standby
> +Date:		November 2024
> +Contact:	Antheas Kapenekakis <lkml@antheas.dev>
> +Description:
> +		The /sys/power/standby file controls the standby state of the
> +		system. Modern S0ix capable systems can enter a set of low power
> +		states while the kernel is still active. Transitioning into those
> +		states may 1) deactivate tertiary hardware, and 2) change the
> +		presentation of the device (e.g., pulse the suspend light, turn
> +		off the keyboard backlight).
> +
> +		Available states are "active" (fully active), "screen-off" (fully
> +		active but all displays of the system are off; virtual and real),
> +		"sleep" (major userspace components have been frozen; light
> +		background tasks may still run; this state may affect the power
> +		envelope of the device). The final state is DRIPS or LSP0, where
> +		the kernel suspends, and is entered by writing "mem" to
> +		/sys/power/state. There is a secondary sleep state called "resume"
> +		that can only be entered from "sleep" and is used in certain
> +		devices to boost the Power Limit (PLx) while remaining in sleep
> +		to hasten preparing for transitioning to "active".
> +
> +		Writing one of the above strings to this file causes the system
> +		to transition into the corresponding state, by firing the
> +		corresponding firmware notifications during the transition.
> +
> +		DRIPS or LSP0 (i.e., mem "s2idle") can only be entered from the
> +		"sleep" state. If the kernel is asked to transition to DRIPS from
> +		a different state, it will transition to "sleep" and then suspend.
> +		On wakeup, the kernel will transition back to the previous state.
> +
> +		See Documentation/admin-guide/pm/standby-states.rst for more
> +		information.
> +
>  What:		/sys/power/disk
>  Date:		September 2006
>  Contact:	Rafael J. Wysocki <rjw@rjwysocki.net>
> diff --git a/kernel/power/main.c b/kernel/power/main.c
> index 6254814d4817..4377fdaf4a8d 100644
> --- a/kernel/power/main.c
> +++ b/kernel/power/main.c
> @@ -748,6 +748,80 @@ 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 turn on display).
> + * See Documentation/admin-guide/pm/standby-states.rst for a description of
> + * what they mean.
> + *
> + * store() accepts one of those strings, translates it into the proper
> + * enumerated value, and initiates a transition to that standby state.
> + *
> + * When the system suspends, it will first enter the state "sleep", suspend,
> + * and then restore the last state before entering "sleep". I.e., if userspace
> + * is not S0ix-aware, the transitions expected by Modern Standby devices will
> + * always be performed.
> + */
> +static ssize_t standby_show(struct kobject *kobj, struct kobj_attribute *attr,
> +			  char *buf)
> +{
> +	char *s = buf;

Instead of char *, add size_t len for the offset.

Order these to reverse xmas tree.

> +	standby_state_t i;
> +	standby_state_t curr = pm_standby_state();
> +
> +	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]);

Do not use sprintf() for anything new.

For sysfs, sysfs_emit_at() (or sysfs_emit()) is the correct function.

You could consider using reverse logic + continue to bring down the 
indentation level.

> +
> +	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;

size_t

> +	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))

Isn't len == strlen(label) && !strncmp(buf, label, len) same as using just
using !strcmp() ?

> +			return state;
> +	}
> +
> +	return PM_STANDBY_MAX;
> +}
> +
> +static ssize_t standby_store(struct kobject *kobj, struct kobj_attribute *attr,
> +			   const char *buf, size_t n)
> +{
> +	int error;
> +	standby_state_t state;
> +
> +	state = decode_standby_state(buf, n);
> +
> +	if (state >= PM_STANDBY_MAX)
> +		return -EINVAL;
> +
> +	error = pm_standby_transition(state);
> +	return error ? error : n;

return error ?: n

> +}
> +
> +power_attr(standby);
> +#endif
> +
>  #ifdef CONFIG_PM_SLEEP
>  /*
>   * The 'wakeup_count' attribute, along with the functions defined in
> @@ -974,6 +1048,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,
> 

-- 
 i.


  reply	other threads:[~2024-11-28 11:45 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-21 17:22 [RFC 00/13] acpi/x86: s2idle: implement Modern Standby transition states and expose to userspace Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 01/13] Documentation: PM: Add documentation for S0ix Standby States Antheas Kapenekakis
2024-11-21 18:58   ` Mario Limonciello
2024-11-21 19:11     ` Antheas Kapenekakis
2024-11-21 19:40       ` Mario Limonciello
2024-11-21 20:33         ` Antheas Kapenekakis
2024-11-21 21:08           ` Mario Limonciello
2024-11-21 21:23             ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 02/13] acpi/x86: s2idle: add support for Display Off and Display On callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 03/13] acpi/x86: s2idle: add support for Sleep Entry and Sleep Exit callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 04/13] acpi/x86: s2idle: add support for Turn On Display callback Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 05/13] acpi/x86: s2idle: add modern standby transition function Antheas Kapenekakis
2024-11-21 18:15   ` Mario Limonciello
2024-11-21 18:29     ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 06/13] acpi/x86: s2idle: rename Screen On/Off to Display On/Off Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 07/13] acpi/x86: s2idle: call Display On/Off as part of callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 08/13] acpi/x86: s2idle: rename MS Exit/Entry to Sleep Exit/Entry Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 09/13] acpi/x86: s2idle: call Sleep Entry/Exit as part of callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 10/13] acpi/x86: s2idle: add Turn On Display and call as part of callback Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 11/13] acpi/x86: s2idle: add quirk table for modern standby delays Antheas Kapenekakis
2024-11-21 18:04   ` Mario Limonciello
2024-11-21 18:19     ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 12/13] platform/x86: asus-wmi: remove Ally (1st gen) and Ally X suspend quirk Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 13/13] PM: standby: Add sysfs attribute for modern standby transitions Antheas Kapenekakis
2024-11-28 11:45   ` Ilpo Järvinen [this message]
2024-11-21 17:41 ` [RFC 00/13] acpi/x86: s2idle: implement Modern Standby transition states and expose to userspace Rafael J. Wysocki
2024-12-06 21:37   ` Antheas Kapenekakis
2024-11-22 19:25 ` Xaver Hugl
2024-11-22 23:55   ` 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=ae43443d-74a8-799d-26aa-608af973a9e8@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hdegoede@redhat.com \
    --cc=linux-pm@vger.kernel.org \
    --cc=lkml@antheas.dev \
    --cc=mario.limonciello@amd.com \
    --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