From nobody Sat Feb 7 06:14:51 2026 Received: from relay10.grserver.gr (relay10.grserver.gr [37.27.248.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD46F15530C; Fri, 26 Dec 2025 10:36:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.27.248.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745406; cv=none; b=sEL9jjNvoSN18S+QV3jowIy5Fo+JMbXAadMnlxyitx3lzPdTPXvTZ5QFzzi65smLNQUWmeglTZ/XaedXu4dGqKEmhHadGqG/lQk/TYwC6sBx8+aFNDmoyLs3TRy3LTksqxIXqmL9Obu9W7YYJYSS7c5DZFp9Tt1RuVA2tJr22sw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745406; c=relaxed/simple; bh=fXN5mv8P1kI8mWWFE4AOg1cXqgCwS6BykBnWRCshjsw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=q8UfiKMsT2JjX29JAdG0W0Q4l2G9IrhHD8uUX5CAmPcmDvrI/+9k5dJOQJ/PfAshkBrf5l91TTdEdzVJlypmyRpfNmGtP/vQIjQkoBWlSMeC3Y6EvwZzt2BpD99LNvq5/VWrNQY3JurFOdx+ep17Z832abyZPvHj9NYNIZ/ss9U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=KUSqPMmx; arc=none smtp.client-ip=37.27.248.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="KUSqPMmx" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id EE35E3F41F; Fri, 26 Dec 2025 12:27:41 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay10.grserver.gr (Proxmox) with ESMTPS id 13BA53F41A; Fri, 26 Dec 2025 12:27:41 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 20D18200D51; Fri, 26 Dec 2025 12:27:39 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744860; bh=uyXMiup/vHvKvja+QJq/TnejqQlHRb09JG6xpCU5VpU=; h=From:To:Subject; b=KUSqPMmxaMl0HwhxMoQ15FQxqftroZxch/oJ63Op6Y99Ar82qQmQMWMwsL5/OOGkZ SY60+f2CUBbhsarhVU4mXPBc8CIJSl70o/n5/xnhqVrJ18WIyQ1hDJGchaw3L26mvO cntTto1rTEn3frZuR8Ci41u/I2V3x0i6YTdnovuyqfELb6wHVfdmzGuufDpjBY7Fko Yw18YMESIworvhpT1d57OoMB4HXBKkB7FKOvylIVr2jU85L4UkukijGdDfB41tbedZ om+dFv1Cuz+loXqHLw9FW6WJrYRsGN4apVO1bNjOtH7P3/ubeMmJv2LKco+V/Etk5p 2I98bDp7r/QWw== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 1/8] Documentation: PM: Add documentation for Runtime Standby States Date: Fri, 26 Dec 2025 12:26:39 +0200 Message-ID: <20251226102656.6296-2-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486055.2608234.5899126676132951757@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Introduce the runtime standby state ABI, which allows for firing the Modern Standby firmware notifications found in Windows during runtime. These notifications allow to make systems that support them look suspended. Signed-off-by: Antheas Kapenekakis --- Documentation/ABI/testing/sysfs-power | 20 ++++ .../admin-guide/pm/standby-states.rst | 100 ++++++++++++++++++ Documentation/admin-guide/pm/system-wide.rst | 1 + 3 files changed, 121 insertions(+) create mode 100644 Documentation/admin-guide/pm/standby-states.rst diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/test= ing/sysfs-power index d38da077905a..16378be2dc13 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power @@ -39,6 +39,26 @@ Description: See Documentation/admin-guide/pm/sleep-states.rst for more information. =20 +What: /sys/power/standby +Date: February 2026 +Contact: Antheas Kapenekakis +Description: + The /sys/power/standby file allows userspace to inform the + kernel of the current runtime standby mode depending on user + activity. The options are "active", "inactive", "sleep", + and "resume". Only the ones supported by the platform will be + available. Depending on the mode, the appearance of the device + will change (e.g., keyboard backlight will turn off as part of + "inactive"), and its thermal envelope might be affected. + + Reading from this file returns the available standby modes, + with the current one enclosed in square brackets. Writing one + of the above strings to this file causes the kernel to + transition to it. + + See Documentation/admin-guide/pm/standby-states.rst for more + information. + What: /sys/power/disk Date: September 2006 Contact: Rafael J. Wysocki diff --git a/Documentation/admin-guide/pm/standby-states.rst b/Documentatio= n/admin-guide/pm/standby-states.rst new file mode 100644 index 000000000000..af7f32721d1c --- /dev/null +++ b/Documentation/admin-guide/pm/standby-states.rst @@ -0,0 +1,100 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Runtime Standby States +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +:Copyright: |copy| 2026 Antheas Kapenekakis + +:Author: Antheas Kapenekakis + +This document describes the runtime standby states ABI available in the Li= nux +kernel, which is designed as a generic superset of the s0ix/Modern Standby +firmware notifications. Devices with these notifications support hardware = states +where they look like they are asleep, while still performing basic computa= tion. +Specifically, those are "Sleep", "Inactive", and "Active" states, with an +additional state "Resume". Transitioning between these states follows the +flowchart below. + +Runtime Standby States +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +The following runtime standby are supported:: + + =E2=86=94 =E2=86=94 =E2=86=94 + =E2=86=92 =E2=86=92 =E2=86=91 + +.. _s2idle_drips: + + +.. _s2idle_active: + +Active +------ + +The "Active" state is the default state of the system and the one it has w= hen +it is turned on. It is the state where the device is on, and the user is +interacting with it. + +.. _s2idle_screen_off: + +Inactive +---------- + +The "Inactive" state is a state in which users have stopped interacting wi= th +the device, e.g., 5 seconds after the displays have turned off due to inac= tivity +or due to the user pressing the power button. It is the responsibility of +userspace to keep track of user interaction so it can inform the kernel to +transition to this state. The response to this state for devices that supp= ort +is to turn off their keyboard backlight, and some might pulse their power = light. + +.. _s2idle_sleep: + +Sleep +----- + +In the sleep state, certain devices will limit their thermal envelope so i= t is +safe for them to be put into a bag and still perform basic computation suc= h as +fetching email. Then, some devices will pulse their power light. Userspace= can +use this state to perform basic tasks such as wake-up checks while maintai= ning +the appearance the device is asleep. + +.. _s2idle_resume: + +Resume +------ + +The resume state is a transient state that may only be entered from the sl= eep +state. It can be used to notify hardware that the device should boost its +thermal envelope as preparation for the user interacting with it. As in, it +undoes the thermal envelope effects of the "sleep" state while keeping its +appearance. + +S2idle +----- + +The "S2idle" state in the diagram corresponds to suspending normally by wr= iting +``mem`` to ``/sys/power/state``. Userspace is fully frozen, and the kernel= parks +the CPUs and turns off most devices. It is shown in the graph as a referen= ce. +If the runtime standby state is not "sleep" when entering s2idle, the kern= el +will first transition to "sleep" before entering s2idle. + +Basic ``sysfs`` Interface for runtime standby transitions +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The file :file:`/sys/power/standby` can be used to transition the system b= etween +the different standby states. The file accepts the following values: ``act= ive``, +``inactive``, ``sleep``, and ``resume``. File writes will block until the +transition completes. The system will cross all states shown in the flowch= art +above to reach the desired state. It will return ``-EINVAL`` when asking f= or an +unsupported state or, e.g., requesting ``resume`` when not in the ``sleep`` +state. If there is an error during the transition, the transition will pau= se on +the last error-free state and return an error. + +The file can be read to retrieve the current state (and potential ones) wi= th the +following format: ``[active] inactive sleep resume``. Only supported states +will be shown. + +Userspace may transition between all supported states including s2idle +arbitrarily, except for the ``resume`` state which may only be requested f= rom +the ``sleep`` state. \ No newline at end of file diff --git a/Documentation/admin-guide/pm/system-wide.rst b/Documentation/a= dmin-guide/pm/system-wide.rst index 1a1924d71006..411775fae4ac 100644 --- a/Documentation/admin-guide/pm/system-wide.rst +++ b/Documentation/admin-guide/pm/system-wide.rst @@ -8,4 +8,5 @@ System-Wide Power Management :maxdepth: 2 =20 sleep-states + standby-states suspend-flows --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay11.grserver.gr (relay11.grserver.gr [78.46.171.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F5A8314D0F; Fri, 26 Dec 2025 10:27:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=78.46.171.57 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744873; cv=none; b=LOhIz+q5vEUNa//3tuo4KzjHf2h59hC1cmiChqaY+40CPf7DuTLdQjQ7IQAmmP3SsDOpWjZP+AWQ22KAghZmABtZoxF1ZImn3gTxU3bMGxKwl2cKNqeKJzVjT3ArtGxWgEcXtxGfu5/dvZTzHZDE3jzUvEkevW32BHE1dYGqA+A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744873; c=relaxed/simple; bh=4hqf5rS2bfwFvwbCJlmmrloIZ4v2ItiJpg+F3qHUwXI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jE+Dco7zQibirPemLwxN/U7lfOscwC6ZwQyu+gWxYCxJJ1mnSjfEqejgddc3I/oOEIp1e9WfOWqSPJnTXWHSocBapuaQr5Brk2ybJmOUKvtIqXaZmWDi2cI+e6Ivd/okNr4UGQ3z7d5vOTf0LpWYVgs9aToDJr6UsITJoagQRwg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=F9X19xtv; arc=none smtp.client-ip=78.46.171.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="F9X19xtv" Received: from relay11 (localhost.localdomain [127.0.0.1]) by relay11.grserver.gr (Proxmox) with ESMTP id 6FE8CC2472; Fri, 26 Dec 2025 12:27:43 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay11.grserver.gr (Proxmox) with ESMTPS id BC2CFC1921; Fri, 26 Dec 2025 12:27:42 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id E965D200D44; Fri, 26 Dec 2025 12:27:40 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744862; bh=LiOshHGRwJ9kf6zmx7ZpAhOgcdHT3lRX/PPYtrOsoyI=; h=From:To:Subject; b=F9X19xtvhUEsVGLEremhLCyijTX7GEIEm7eihJOyFT1PUiZrwUDLuwTbFJDjSBOY0 9C1OU/89QE7Gu0WiyRwuoD9nrdfrhOWC55QTBWDPkrE7vwBE3wxmA63Xs2nVuuNeG1 SR3q84fTjf8A35YbTUwunJF3VuJVvNowLtUYEISL8VjoLeEdPcNw0OQ9C7qMhmsCyA 6GaETnJ7IbSHuBGOjvaDA0qYwUXacGSutO+T6P9jI5/zv1Wm9F8uBQJVKo6JgDax1X bBLUQABwFyLIgE+HWCY48Nc54+l3kaZcyoUhZh2jtpzTYCwvyUL58tkpPHHwqx7H/o +2ltuvDAvpDHA== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 2/8] acpi/x86: s2idle: Rename LPS0 constants so they mirror their function Date: Fri, 26 Dec 2025 12:26:40 +0200 Message-ID: <20251226102656.6296-3-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486237.2608281.13875257044813946897@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" The LPS0 3/4 constants are part of a firmware notification called "Display on/off", in which the device enters a "Screen Off" state. The LPS0 7/8 constants are part of a firmware notification in which a Windows modern standby computer enters a "sleep" state where the CPU may still be active and maintain the radios. However, currently, the values are named as "Screen on/off" and "MS entry/exit", where Modern Standby is abbreviated as "MS". Therefore, perform a minor rename so that the values match their function. Then, fix the debug message to say that it executes notifications instead of entering states as it is otherwise confusing. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 6d4d06236f61..1f13c8b0ef83 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -39,19 +39,19 @@ static const struct acpi_device_id lps0_device_ids[] = =3D { #define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" =20 #define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1 -#define ACPI_LPS0_SCREEN_OFF 3 -#define ACPI_LPS0_SCREEN_ON 4 +#define ACPI_LPS0_DISPLAY_OFF 3 +#define ACPI_LPS0_DISPLAY_ON 4 #define ACPI_LPS0_ENTRY 5 #define ACPI_LPS0_EXIT 6 -#define ACPI_LPS0_MS_ENTRY 7 -#define ACPI_LPS0_MS_EXIT 8 +#define ACPI_LPS0_SLEEP_ENTRY 7 +#define ACPI_LPS0_SLEEP_EXIT 8 =20 /* AMD */ #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" #define ACPI_LPS0_ENTRY_AMD 2 #define ACPI_LPS0_EXIT_AMD 3 -#define ACPI_LPS0_SCREEN_OFF_AMD 4 -#define ACPI_LPS0_SCREEN_ON_AMD 5 +#define ACPI_LPS0_DISPLAY_OFF_AMD 4 +#define ACPI_LPS0_DISPLAY_ON_AMD 5 =20 static acpi_handle lps0_device_handle; static guid_t lps0_dsm_guid; @@ -340,25 +340,25 @@ static const char *acpi_sleep_dsm_state_to_str(unsign= ed 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_DISPLAY_OFF: + return "display off"; + case ACPI_LPS0_DISPLAY_ON: + return "display 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"; + case ACPI_LPS0_SLEEP_ENTRY: + return "sleep entry"; + case ACPI_LPS0_SLEEP_EXIT: + return "sleep 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_DISPLAY_ON_AMD: + return "display on"; + case ACPI_LPS0_DISPLAY_OFF_AMD: + return "display off"; case ACPI_LPS0_ENTRY_AMD: return "lps0 entry"; case ACPI_LPS0_EXIT_AMD: @@ -383,7 +383,7 @@ static void acpi_sleep_run_lps0_dsm(unsigned int func, = unsigned int func_mask, g lps0_dsm_state =3D func; if (pm_debug_messages_on) { acpi_handle_info(lps0_device_handle, - "%s transitioned to state %s\n", + "%s executed notification %s\n", out_obj ? "Successfully" : "Failed to", acpi_sleep_dsm_state_to_str(lps0_dsm_state)); } @@ -545,12 +545,12 @@ static int acpi_s2idle_prepare_late_lps0(void) /* Screen off */ if (lps0_dsm_func_mask > 0) acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? - ACPI_LPS0_SCREEN_OFF_AMD : - ACPI_LPS0_SCREEN_OFF, + ACPI_LPS0_DISPLAY_OFF_AMD : + ACPI_LPS0_DISPLAY_OFF, lps0_dsm_func_mask, lps0_dsm_guid); =20 if (lps0_dsm_func_mask_microsoft > 0) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF, + acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_OFF, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); =20 /* LPS0 entry */ @@ -560,7 +560,7 @@ static int acpi_s2idle_prepare_late_lps0(void) =20 if (lps0_dsm_func_mask_microsoft > 0) { /* Modern Standby entry */ - acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY, + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); @@ -613,18 +613,18 @@ static void acpi_s2idle_restore_early_lps0(void) acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); /* Modern Standby exit */ - acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT, + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_EXIT, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); } =20 /* Screen on */ if (lps0_dsm_func_mask_microsoft > 0) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON, + acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_ON, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); if (lps0_dsm_func_mask > 0) acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? - ACPI_LPS0_SCREEN_ON_AMD : - ACPI_LPS0_SCREEN_ON, + ACPI_LPS0_DISPLAY_ON_AMD : + ACPI_LPS0_DISPLAY_ON, lps0_dsm_func_mask, lps0_dsm_guid); } =20 --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay13.grserver.gr (relay13.grserver.gr [178.156.171.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAB118479; Fri, 26 Dec 2025 10:33:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.156.171.147 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745202; cv=none; b=j6XlkNDlVooE96JIJma0is/qrvURDInCAzSXxTg1mY0062lfcZgI+fOQdlK5onkJ1pKvzlR3Kh+1x1fRyf+wHOvrz5H5M0PbKse03sk6qzOAfONUfH9Sm+ki1qs6nMS9I+bwY/ygupRWX/HCXGx279xdzFw5YyDvMyVZpGD52b4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745202; c=relaxed/simple; bh=KctfpyIEpIPYB4mHIWJEdk7L0bUqUBoP5bWqMmAm8JY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SPgKa0EnydUaCxUIfSE0WePGr1hfHfBoirCsKqCq/gY7vrHy7G49RzqbQzh6p+3kYP8JPR1efDKPB0nM3zMD3wGXT76Yf5Czs23Q5KAl6Msfu4lxhcNlw7YVd+Da7e81bLx88iKQlszkMMcdWlD2Qt5urZiqRDmPePpZVUg6pj0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=BLCgJE+W; arc=none smtp.client-ip=178.156.171.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="BLCgJE+W" Received: from relay13 (localhost [127.0.0.1]) by relay13.grserver.gr (Proxmox) with ESMTP id 0A9305E545; Fri, 26 Dec 2025 12:27:46 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay13.grserver.gr (Proxmox) with ESMTPS id 1B2F85E550; Fri, 26 Dec 2025 12:27:45 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id C04C3200D51; Fri, 26 Dec 2025 12:27:42 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744864; bh=n9mpJSPwpXWXzmQPXHG/E/RkCR3w/MEYONhtJcXWMls=; h=From:To:Subject; b=BLCgJE+W2GRfoJsKrTCA1TTpEgDqDIgpgO7kkXWleLz8ySEFBjVnLS5GHaf9c1Fdu Gi6CHdAXMkQpndXmFl5cCuur6jgXSuiHpytKKWBSIau/2YIZ8EL6Qi9zT+pUwSebQg j9ai3Ti4aWJ2jbwSSh4hZ1/p9ZsEzNkriFMGj/+iW+m+PSaUkEqVOwwaF+HSiEGI3T g7J+16gk+YJG3ulzWe4sGhfQhBV8W2yl0G0sJDAygROu0leLbszbakQRsWQ9o2QXFi BKvZQrMKAi8LWQ2EMZjbTDTP2YITCoCqXiIyniysMpSn4N9JWO3tPeszWjQc+4qUlK qqPz4jVgRXocQ== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 3/8] acpi/x86: s2idle: add runtime standby transition function Date: Fri, 26 Dec 2025 12:26:41 +0200 Message-ID: <20251226102656.6296-4-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486420.2608355.10993945246372674856@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Add pm_standby_transition() to allow transitioning between standby states during runtime and implement it as part of the s2idle suspend sequence. Update the platform_s2idle_ops structure to include a function to perform firmware notifications and a function to get supported states Standby states are a way for userspace to indicate the interactivity of the system at the current moment. Active means that the user is interacting with the device, inactive that a user is not actively interacting with the device, and sleep that the system should appear as if it is suspended to the user, but may still perform small background tasks. For modern ACPI s0ix laptops, the inactive state turns off the backlight and the sleep state may limit the thermal envelope of the device. Either may pulse the power light. This patch introduces an ACPI agnostic structure to handle these transitions, so they may implemented by other platforms, and does not implement them for ACPI. Signed-off-by: Antheas Kapenekakis --- include/linux/suspend.h | 26 +++++++ kernel/power/suspend.c | 153 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index b02876f1ae38..916dee124758 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -40,6 +40,25 @@ typedef int __bitwise suspend_state_t; #define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) =20 +typedef int __bitwise standby_state_t; + +#define PM_STANDBY_ACTIVE ((__force standby_state_t) 0) +#define PM_STANDBY_INACTIVE ((__force standby_state_t) 1) +#define PM_STANDBY_SLEEP ((__force standby_state_t) 2) +#define PM_STANDBY_RESUME ((__force standby_state_t) 3) +#define PM_STANDBY_MIN PM_STANDBY_ACTIVE +#define PM_STANDBY_MAX ((__force standby_state_t) 4) + +typedef int __bitwise standby_notification_t; + +#define PM_SN_INACTIVE_ENTRY ((__force standby_notification_t) 0) +#define PM_SN_INACTIVE_EXIT ((__force standby_notification_t) 1) +#define PM_SN_SLEEP_ENTRY ((__force standby_notification_t) 2) +#define PM_SN_SLEEP_EXIT ((__force standby_notification_t) 3) +#define PM_SN_RESUME ((__force standby_notification_t) 4) +#define PM_SN_MIN PM_STANDBY_DISPLAY_OFF +#define PM_SN_MAX ((__force standby_notification_t) 5) + /** * struct platform_suspend_ops - Callbacks for managing platform dependent * system sleep states. @@ -132,6 +151,8 @@ struct platform_suspend_ops { }; =20 struct platform_s2idle_ops { + u8 (*get_standby_states)(void); + int (*do_notification)(standby_notification_t state); int (*begin)(void); int (*prepare)(void); int (*prepare_late)(void); @@ -276,6 +297,11 @@ extern void arch_suspend_enable_irqs(void); =20 extern int pm_suspend(suspend_state_t state); extern bool sync_on_suspend_enabled; + +extern void pm_standby_refresh_states(void); +extern int pm_standby_transition(standby_state_t state); +extern void pm_standby_set_state(standby_state_t state); +extern int pm_standby_get_state(void); #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL =20 diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 2da4482bb6eb..ede1ba483fa5 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -46,12 +46,21 @@ static const char * const mem_sleep_labels[] =3D { [PM_SUSPEND_MEM] =3D "deep", }; const char *mem_sleep_states[PM_SUSPEND_MAX]; +static const char * const standby_labels[] =3D { + [PM_STANDBY_ACTIVE] =3D "active", + [PM_STANDBY_INACTIVE] =3D "inactive", + [PM_STANDBY_SLEEP] =3D "sleep", + [PM_STANDBY_RESUME] =3D "resume", +}; +const char *standby_states[PM_STANDBY_MAX]; =20 suspend_state_t mem_sleep_current =3D PM_SUSPEND_TO_IDLE; suspend_state_t mem_sleep_default =3D PM_SUSPEND_MAX; suspend_state_t pm_suspend_target_state; EXPORT_SYMBOL_GPL(pm_suspend_target_state); =20 +standby_state_t standby_current =3D PM_STANDBY_ACTIVE; + unsigned int pm_suspend_global_flags; EXPORT_SYMBOL_GPL(pm_suspend_global_flags); =20 @@ -195,6 +204,9 @@ void __init pm_states_init(void) * initialize mem_sleep_states[] accordingly here. */ mem_sleep_states[PM_SUSPEND_TO_IDLE] =3D mem_sleep_labels[PM_SUSPEND_TO_I= DLE]; + + /* Always support the active runtime standby state. */ + standby_states[PM_STANDBY_ACTIVE] =3D standby_labels[PM_STANDBY_ACTIVE]; } =20 static int __init mem_sleep_default_setup(char *str) @@ -334,6 +346,141 @@ static bool platform_suspend_again(suspend_state_t st= ate) suspend_ops->suspend_again() : false; } =20 +static int platform_standby_notify(standby_notification_t state) +{ + return s2idle_ops && s2idle_ops->do_notification ? + s2idle_ops->do_notification(state) : + 0; +} + +/** + * pm_standby_refresh_states - Refresh the supported runtime standby states + */ +void pm_standby_refresh_states(void) +{ + u8 standby_support =3D s2idle_ops && s2idle_ops->get_standby_states ? + s2idle_ops->get_standby_states() : + 0; + + standby_states[PM_STANDBY_INACTIVE] =3D + standby_support & BIT(PM_STANDBY_INACTIVE) ? + standby_labels[PM_STANDBY_INACTIVE] : + NULL; + standby_states[PM_STANDBY_SLEEP] =3D + standby_support & BIT(PM_STANDBY_SLEEP) ? + standby_labels[PM_STANDBY_SLEEP] : + NULL; + standby_states[PM_STANDBY_RESUME] =3D + standby_support & BIT(PM_STANDBY_RESUME) ? + standby_labels[PM_STANDBY_RESUME] : + NULL; +} +EXPORT_SYMBOL_GPL(pm_standby_refresh_states); + +/** + * pm_standby_transition - Transition between standby states + * + * Configure the runtime standby state of the system. Entering these states + * may change the appearance of the system (e.g., keyboard backlight) or l= imit + * the thermal envelope of the system (e.g., PLx to 5W). + * + * Returns an error if the transition fails. The function does not rollbac= k. + */ +int pm_standby_transition(standby_state_t state) +{ + int error; + + if (state =3D=3D standby_current) + return 0; + if (state > PM_STANDBY_MAX) + return -EINVAL; + + pm_standby_refresh_states(); + + pm_pr_dbg("Transitioning from standby state %s to %s\n", + standby_states[standby_current], standby_states[state]); + + /* Resume can only be entered if we are on the sleep state. */ + if (state =3D=3D PM_STANDBY_RESUME) { + if (standby_current !=3D PM_STANDBY_SLEEP) + return -EINVAL; + standby_current =3D PM_STANDBY_RESUME; + return platform_standby_notify(PM_SN_RESUME); + } + + /* + * The system should not be able to re-enter Sleep from resume as it + * is undefined behavior. As part of setting the state to "Resume", + * userspace promised a transition to "Inactive" or "Active". + */ + if (standby_current =3D=3D PM_STANDBY_RESUME && state =3D=3D PM_STANDBY_S= LEEP) + return -EINVAL; + + /* Resume is the Sleep state logic-wise. */ + if (standby_current =3D=3D PM_STANDBY_RESUME) + standby_current =3D PM_STANDBY_SLEEP; + + if (standby_current < state) { + for (; standby_current < state; standby_current++) { + switch (standby_current + 1) { + case PM_STANDBY_INACTIVE: + error =3D platform_standby_notify(PM_SN_INACTIVE_ENTRY); + break; + case PM_STANDBY_SLEEP: + error =3D platform_standby_notify(PM_SN_SLEEP_ENTRY); + break; + } + + if (error) { + /* Rollback to previous valid state */ + while (standby_current > PM_STANDBY_ACTIVE && + !standby_states[standby_current]) + standby_current--; + return error; + } + } + } else if (standby_current > state) { + for (; standby_current > state; standby_current--) { + switch (standby_current) { + case PM_STANDBY_SLEEP: + error =3D platform_standby_notify(PM_SN_SLEEP_EXIT); + break; + case PM_STANDBY_INACTIVE: + error =3D platform_standby_notify(PM_SN_INACTIVE_EXIT); + break; + } + + if (error) { + /* Rollback to previous valid state */ + while (standby_current < PM_STANDBY_SLEEP && + !standby_states[standby_current]) + standby_current++; + return error; + } + } + } + + return 0; +} + +/** + * pm_standby_set_state - Set the current standby state and skip the trans= ition + */ +void pm_standby_set_state(standby_state_t state) +{ + standby_current =3D state; +} +EXPORT_SYMBOL_GPL(pm_standby_set_state); + +/** + * pm_standby_get_state - Returns the current standby state + */ +int pm_standby_get_state(void) +{ + return standby_current; +} +EXPORT_SYMBOL_GPL(pm_standby_get_state); + #ifdef CONFIG_PM_DEBUG static unsigned int pm_test_delay =3D 5; module_param(pm_test_delay, uint, 0644); @@ -572,6 +719,7 @@ static void suspend_finish(void) */ static int enter_state(suspend_state_t state) { + standby_state_t standby_prior; int error; =20 trace_suspend_resume(TPS("suspend_enter"), state, true); @@ -588,6 +736,9 @@ static int enter_state(suspend_state_t state) if (!mutex_trylock(&system_transition_mutex)) return -EBUSY; =20 + standby_prior =3D standby_current; + pm_standby_transition(PM_STANDBY_SLEEP); + if (state =3D=3D PM_SUSPEND_TO_IDLE) s2idle_begin(); =20 @@ -619,6 +770,8 @@ static int enter_state(suspend_state_t state) pm_pr_dbg("Finishing wakeup.\n"); suspend_finish(); Unlock: + pm_standby_transition(standby_prior); + mutex_unlock(&system_transition_mutex); return error; } --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay12.grserver.gr (relay12.grserver.gr [88.99.38.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BA0F22097; Fri, 26 Dec 2025 10:32:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=88.99.38.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745179; cv=none; b=jauzQHaCd7x+j94W60FybHMal4/1lM2bFaBXkvSnRZzUF2HzDO98oOdTONtlplgM33TTotRCpvxQjDxB0gdrHOoLkG2QkfAC8YoHewnHoM70uPM9/LEYy1TF9FixwU7A8XO1RK34CXB3C47ofBePMRKs8TZ9Rh+3kAg1wPN6HMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745179; c=relaxed/simple; bh=2HKh3VVDcTLF6cYVYZwPDDOfOEz05QlmGVqz0NeNl9c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uoop/jHlpMZOiG4RI5AiePOJSc/T3xuexquKUEseWAgBjRIOU0gkHMeSDpfvVT/qWd3iZCi6shv0/eL5+Oxz6tHdM585wqaftPnCABii0tnibowUTi4zpalJ9pXKUjK8YQVPhyGpBf+hzglZwpGFFxCaFIBvmmhPJjDSS7yTIus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=X+ibKlEF; arc=none smtp.client-ip=88.99.38.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="X+ibKlEF" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id 0AA94BD9F9; Fri, 26 Dec 2025 12:27:47 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay12.grserver.gr (Proxmox) with ESMTPS id 78D38BC770; Fri, 26 Dec 2025 12:27:46 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 99FCF200D44; Fri, 26 Dec 2025 12:27:44 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744866; bh=ztcI+T5xyH1Iqv/Hfp0urWUwZszOLISihCn6mTknRkk=; h=From:To:Subject; b=X+ibKlEF1E/M7FqaRK0oV2ZMYfDEvmBph1XDmCc5FPgET/rbuLn378sYnOR5sdubD kkDio8aWDenTDovx0ikSdDMrws/jjrsyR4o6GsncposQH27MfWzIRuN3F0jXt0eAAm ylcxEi2igjlHL+q39PGlp/C0UqKFPvSq+2yUMr7A2i0lk6992cv5m+H2TmW4YVhPM0 2JbqdK0ef8qxpiVM7cOKyKTz7vkaH2gVIfrUYNoSDxt3GnE2N1/sCknx0y01VOmSsg xd6pwqH2jsoaUqu92+vHOX/C7Pv+ov+H9sUGWNF2OTNS0MkCzVUf+L5bSke3ZhFqxD wb1Zj+g73i8Pg== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 4/8] acpi/x86: s2idle: add support for querying runtime standby state support Date: Fri, 26 Dec 2025 12:26:42 +0200 Message-ID: <20251226102656.6296-5-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486607.2608443.11642982308655321183@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Implement the platform_s2idle_ops->get_standby_states() callback to query which modern standby states are supported by the platform based on the dsm func masks and expose those to the kernel as runtime standby states. Union the vendor specific AMD/Intel masks with the ones from Microsoft as some laptops implement both of them. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 1f13c8b0ef83..08fa7841a484 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -513,6 +513,40 @@ static struct acpi_scan_handler lps0_handler =3D { .attach =3D lps0_device_attach, }; =20 +static u8 acpi_s2idle_get_standby_states(void) +{ + u8 states =3D 0; + + if (!lps0_device_handle || sleep_no_lps0) + return 0; + + if (lps0_dsm_func_mask_microsoft > 0) { + states |=3D BIT(PM_STANDBY_ACTIVE); + if (lps0_dsm_func_mask_microsoft & + (1 << ACPI_LPS0_DISPLAY_OFF | 1 << ACPI_LPS0_DISPLAY_ON)) + states |=3D BIT(PM_STANDBY_INACTIVE); + if (lps0_dsm_func_mask_microsoft & + (1 << ACPI_LPS0_SLEEP_ENTRY | 1 << ACPI_LPS0_SLEEP_EXIT)) + states |=3D BIT(PM_STANDBY_SLEEP); + } + + if (lps0_dsm_func_mask > 0) { + states |=3D BIT(PM_STANDBY_ACTIVE); + if (acpi_s2idle_vendor_amd()) { + if (lps0_dsm_func_mask & + (1 << ACPI_LPS0_DISPLAY_OFF_AMD | + 1 << ACPI_LPS0_DISPLAY_ON_AMD)) + states |=3D BIT(PM_STANDBY_INACTIVE); + } else { + if (lps0_dsm_func_mask & (1 << ACPI_LPS0_DISPLAY_OFF | + 1 << ACPI_LPS0_DISPLAY_ON)) + states |=3D BIT(PM_STANDBY_INACTIVE); + } + } + + return states; +} + static int acpi_s2idle_begin_lps0(void) { if (pm_debug_messages_on && !lpi_constraints_table) { @@ -629,6 +663,7 @@ static void acpi_s2idle_restore_early_lps0(void) } =20 static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 =3D { + .get_standby_states =3D acpi_s2idle_get_standby_states, .begin =3D acpi_s2idle_begin_lps0, .prepare =3D acpi_s2idle_prepare, .prepare_late =3D acpi_s2idle_prepare_late_lps0, --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay10.grserver.gr (relay10.grserver.gr [37.27.248.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD4EF29A307; Fri, 26 Dec 2025 10:36:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.27.248.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745406; cv=none; b=efMv9Q1qgkQjMub/xyeNou5F4qrvCinqE//0hKEtBgtbad0GmTYQ3pTCjVsVktnvVxl6OlRa165N3FJR7+pdOcXyD5dBA6/4RGvZYjuWYk2akc6OEHYqxPH1FmlRD86o3Ds7uohdHLs44OzglpE3PWVn9Yw5lPw2mDSlwH8Qu+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766745406; c=relaxed/simple; bh=3+5bRz3aGa/fzcAmyVYNGN02MFmipMxO6zvyXLHcC04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cUsJDd+N/z1iUvreeA9rCzwvfmKJO45OrKjl+iYJhyS0fxutlNX4RyqIkNMALD6NP4aT2smdmAyNpEEbj1yTRdUGXoZeMVxIPL3U/em964ZT1wjvEdpg0nOvppypQKothbPQ9QRYgli/Fac1trDt8IQlpXOGG7pCB/xUKBhrvNY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=Ih1hUbW2; arc=none smtp.client-ip=37.27.248.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="Ih1hUbW2" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id 0BA663F421; Fri, 26 Dec 2025 12:27:49 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay10.grserver.gr (Proxmox) with ESMTPS id 6ACE13F41C; Fri, 26 Dec 2025 12:27:48 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 7849E200D51; Fri, 26 Dec 2025 12:27:46 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744868; bh=IIWY/ziOTk5vlnmDAnFLszfbPgF/DV9tjbzBXpl8Ym8=; h=From:To:Subject; b=Ih1hUbW2jfpbdkbpvaBEznukR94Y6SxYg6Av5rKSJG7yZ/8ESbLv9v9OVFFd2FH6B lWT3Qe4JYccOlPgYj1mC0IFanvzp3QUV9meEqmhL+4JFBIsvGxRiyHaQKULGKDHGnV m8j+4nG+BRBAii+U7Uz+Pkbz67Lm8+c1wWno4y3a8soJSsrV/MHXEFHzURwC8q6fzR N/j0ASDbF6FUf+FTJekbuGCfRc0x8emo1URLng/PniLDDKpr2d7W5UqkDND00bvTWl VLg99grT7JIP8zqrBF37U+uL3aJeB7FzL4bjlk6P+13oaOGX/f1bGOBWwXdywwl3pH 6rxtG0tJdDt6A== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 5/8] acpi/x86: s2idle: move DSM notifications to do_notification callback Date: Fri, 26 Dec 2025 12:26:43 +0200 Message-ID: <20251226102656.6296-6-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486790.2608494.3399833283691661815@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Currently, the DSM Sleep Entry/Exit/Display On/Off notifications fire during the suspend sequence. Move them to the new do_notification callback so they can be called during runtime as well. The kernel will still ensure that they are called during s2idle without userspace involvement. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 87 +++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 08fa7841a484..7693162c68fd 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -547,6 +547,53 @@ static u8 acpi_s2idle_get_standby_states(void) return states; } =20 +static int acpi_s2idle_do_notification(standby_notification_t state) +{ + switch ((__force unsigned int)state) { + case PM_SN_INACTIVE_ENTRY: + if (lps0_dsm_func_mask > 0) + acpi_sleep_run_lps0_dsm( + acpi_s2idle_vendor_amd() ? + ACPI_LPS0_DISPLAY_OFF_AMD : + ACPI_LPS0_DISPLAY_OFF, + lps0_dsm_func_mask, lps0_dsm_guid); + + if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_OFF, + lps0_dsm_func_mask_microsoft, + lps0_dsm_guid_microsoft); + break; + case PM_SN_INACTIVE_EXIT: + if (lps0_dsm_func_mask > 0) + acpi_sleep_run_lps0_dsm( + acpi_s2idle_vendor_amd() ? + ACPI_LPS0_DISPLAY_ON_AMD : + ACPI_LPS0_DISPLAY_ON, + lps0_dsm_func_mask, lps0_dsm_guid); + if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_ON, + lps0_dsm_func_mask_microsoft, + lps0_dsm_guid_microsoft); + break; + case PM_SN_SLEEP_ENTRY: + if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_ENTRY, + lps0_dsm_func_mask_microsoft, + lps0_dsm_guid_microsoft); + break; + case PM_SN_SLEEP_EXIT: + if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_EXIT, + lps0_dsm_func_mask_microsoft, + lps0_dsm_guid_microsoft); + break; + default: + return -EINVAL; + } + + return 0; +} + static int acpi_s2idle_begin_lps0(void) { if (pm_debug_messages_on && !lpi_constraints_table) { @@ -576,33 +623,16 @@ static int acpi_s2idle_prepare_late_lps0(void) if (pm_debug_messages_on) lpi_check_constraints(); =20 - /* Screen off */ + /* LPS0 entry */ if (lps0_dsm_func_mask > 0) acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? - ACPI_LPS0_DISPLAY_OFF_AMD : - ACPI_LPS0_DISPLAY_OFF, + ACPI_LPS0_ENTRY_AMD : + ACPI_LPS0_ENTRY, lps0_dsm_func_mask, lps0_dsm_guid); =20 if (lps0_dsm_func_mask_microsoft > 0) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_OFF, - lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - - /* LPS0 entry */ - if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd()) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD, - lps0_dsm_func_mask, lps0_dsm_guid); - - if (lps0_dsm_func_mask_microsoft > 0) { - /* Modern Standby entry */ - acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_ENTRY, - lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - } - - if (lps0_dsm_func_mask > 0 && !acpi_s2idle_vendor_amd()) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY, - lps0_dsm_func_mask, lps0_dsm_guid); =20 list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) { if (handler->prepare) @@ -643,27 +673,14 @@ static void acpi_s2idle_restore_early_lps0(void) ACPI_LPS0_EXIT, lps0_dsm_func_mask, lps0_dsm_guid); =20 - if (lps0_dsm_func_mask_microsoft > 0) { - acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT, - lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - /* Modern Standby exit */ - acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_EXIT, - lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - } - - /* Screen on */ if (lps0_dsm_func_mask_microsoft > 0) - acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_ON, + acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); - if (lps0_dsm_func_mask > 0) - acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? - ACPI_LPS0_DISPLAY_ON_AMD : - ACPI_LPS0_DISPLAY_ON, - lps0_dsm_func_mask, lps0_dsm_guid); } =20 static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 =3D { .get_standby_states =3D acpi_s2idle_get_standby_states, + .do_notification =3D acpi_s2idle_do_notification, .begin =3D acpi_s2idle_begin_lps0, .prepare =3D acpi_s2idle_prepare, .prepare_late =3D acpi_s2idle_prepare_late_lps0, --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay12.grserver.gr (relay12.grserver.gr [88.99.38.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB069314D38; Fri, 26 Dec 2025 10:27:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=88.99.38.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744874; cv=none; b=WCaSzRMw3+RRliaK70R9ssVPk72HriuCkMwSU8MW/K0Iems9o2Tpj72WTrLwJ/4P1TqM2kmSDo43537/l/hoar1gqiplqbF+PwdlLDl/LOPcVLLuziBXeuK5Fl8RaYbakd9gim+Bn9mbtipibhcRWRtQR0f7mtF1Dd846kqge4c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744874; c=relaxed/simple; bh=kU7WKbzAeotw+Yh5dtlEQy3dh22cpZu25cvJtN2jHkM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ICytr0d8VJSjnUChmhNBUihWTxpSql+HovjBqmBmXfVQxV75KTFuvk0I4yCL9foGArGP6uGMWeg/tqeBso7qQfbf0cnGFExE4HwMfO/DrHD7+c3uao1w9w+xCBHYTn9sCXHBYvCVjaVHMvx+68RHFB8kpou7dBFITEpLYqpKnmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=h5ZMRZlc; arc=none smtp.client-ip=88.99.38.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="h5ZMRZlc" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id 42E91BDA27; Fri, 26 Dec 2025 12:27:51 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay12.grserver.gr (Proxmox) with ESMTPS id 70B7ABC770; Fri, 26 Dec 2025 12:27:50 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 4CB77200D44; Fri, 26 Dec 2025 12:27:48 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744870; bh=NIq2lJ/ajRZv+Ep787KnOYWC1DkezUTruLFYn4AKlf8=; h=From:To:Subject; b=h5ZMRZlcuD9/F4+jk6M/TyZi/RBHcLDrr/30dqfoHxQhdVkbh1LCBBMi7jGTe6eqR GdUVmSpj4AkOAXnxw/BS9JKglAFFf0jcIjNDSGYVpvw2oEeRmUDcK9ZeQ6JagsbOUI 2yavYzftn9yEowKwfdEeEW1iluhlTmbNrBQRmxjJ6UCfDJ/ymjsQsznGBqb6TIfd0I VqsGDvRv1o3gCkUa33JSXCTZjq6BMgcALrWQxpNesrVbElL55Ks0OXnRqp3SX0b3wX IFMBUN7PLS2P1NLnzikBFF0hqYFJ6oZsNKDabOT12eXhNNRLGD72Pl2k/2HbbZBDZM 61c3WmgiMpheA== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 6/8] acpi/x86: s2idle: implement turn on display DSM as resume notification Date: Fri, 26 Dec 2025 12:26:44 +0200 Message-ID: <20251226102656.6296-7-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674486991.2608577.4259034392204383426@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Windows implements a DSM called "Turn On Display". This notification is sent to the hardware while on the sleep state if the user interacted with the device and caused it to wake up in such a way where the display should turn on. This allows the OEM to counter the effects of Sleep entry such as a reduced power envelope to allow for the device to wake up faster. Implement it as part of the "resume" state in the Microsoft-agnostic kernel ABI. Link: https://learn.microsoft.com/en-us/windows-hardware/design/device-expe= riences/modern-standby-firmware-notifications Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 7693162c68fd..965b78cc8bf5 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -39,12 +39,13 @@ static const struct acpi_device_id lps0_device_ids[] = =3D { #define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" =20 #define ACPI_LPS0_GET_DEVICE_CONSTRAINTS 1 -#define ACPI_LPS0_DISPLAY_OFF 3 -#define ACPI_LPS0_DISPLAY_ON 4 -#define ACPI_LPS0_ENTRY 5 -#define ACPI_LPS0_EXIT 6 -#define ACPI_LPS0_SLEEP_ENTRY 7 -#define ACPI_LPS0_SLEEP_EXIT 8 +#define ACPI_LPS0_DISPLAY_OFF 3 +#define ACPI_LPS0_DISPLAY_ON 4 +#define ACPI_LPS0_ENTRY 5 +#define ACPI_LPS0_EXIT 6 +#define ACPI_LPS0_SLEEP_ENTRY 7 +#define ACPI_LPS0_SLEEP_EXIT 8 +#define ACPI_LPS0_TURN_ON_DISPLAY 9 =20 /* AMD */ #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" @@ -352,6 +353,8 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned= int state) return "sleep entry"; case ACPI_LPS0_SLEEP_EXIT: return "sleep exit"; + case ACPI_LPS0_TURN_ON_DISPLAY: + return "turn on display"; } } else { switch (state) { @@ -528,6 +531,9 @@ static u8 acpi_s2idle_get_standby_states(void) if (lps0_dsm_func_mask_microsoft & (1 << ACPI_LPS0_SLEEP_ENTRY | 1 << ACPI_LPS0_SLEEP_EXIT)) states |=3D BIT(PM_STANDBY_SLEEP); + if (lps0_dsm_func_mask_microsoft & + (1 << ACPI_LPS0_TURN_ON_DISPLAY)) + states |=3D BIT(PM_STANDBY_RESUME); } =20 if (lps0_dsm_func_mask > 0) { @@ -587,6 +593,12 @@ static int acpi_s2idle_do_notification(standby_notific= ation_t state) lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); break; + case PM_SN_RESUME: + if (lps0_dsm_func_mask_microsoft > 0) + acpi_sleep_run_lps0_dsm(ACPI_LPS0_TURN_ON_DISPLAY, + lps0_dsm_func_mask_microsoft, + lps0_dsm_guid_microsoft); + break; default: return -EINVAL; } --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay10.grserver.gr (relay10.grserver.gr [37.27.248.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 866013164BD; Fri, 26 Dec 2025 10:27:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.27.248.198 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744877; cv=none; b=VM3hJqmKOywzCEXzPw039z21WkrCduy6TISqrZOVLlNhQJI/i50hg3I824U+/NFLoEPlcDv/YQ9z6chhrPeeASGS/PfO9/nNjsxlDJH5Usm7WIPMIaxBSx3UPLVxRKVR7y8LMZcSko76KeOfgTvDq737VH28enRD/2tkQ8XPDGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744877; c=relaxed/simple; bh=2RmJMnjXqESrVBOlyCF4D7Fzx3SWx0PCqIRQbL78fkE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oliluQcAl5Dv2/jes4yKVDmffWE6UM+n65Y0RYRMh6vNb9BNOgPa9gTG2kJsJxWSMv3e1rDF6Or1mnx12V8nSrReBynNPJt/g4mjrBq7p6kUlP8NBFtVqTouiUMGQYfIP3jPD3d5SOxnV9zoNfzj09RKmaw/0lKrqWHQqBLZO+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=gJJ+JH7B; arc=none smtp.client-ip=37.27.248.198 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="gJJ+JH7B" Received: from relay10 (localhost.localdomain [127.0.0.1]) by relay10.grserver.gr (Proxmox) with ESMTP id 10D203F41B; Fri, 26 Dec 2025 12:27:53 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay10.grserver.gr (Proxmox) with ESMTPS id 872D83F3B9; Fri, 26 Dec 2025 12:27:52 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 623CD200D69; Fri, 26 Dec 2025 12:27:50 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744872; bh=1K2j6fb9op9Z8JpPuuVJ8hc0VtRGxEEvu4tC0cvyOHk=; h=From:To:Subject; b=gJJ+JH7BntLBCI3aRGj8A62fS1GcM4dysJm/cHleZ9meama5c48FyOvvPymQYY6Bi PT9e9t5VCuoagWJ9vqZOkSID+lFmCmtKQ3qyPsdMh6oaGD1OFQjNqQaF+VIEWEAFty g4NrLuB/tT1FYB5HLtcfsUwU3Tgz5yI+o12JbDesxDrOrtLX23xOMadBB5Ng7zM+pE Q9ukl43coCSbqnqYw8hqLzw/PX3b2Jn4YaZXAULpcoHYiuCMd1wOxOK7ECUL/Wta9k 30x6i0UAwBtuqXlpb7Ul4iQm4JWQkNc4Ix70PE8oe+ZQZq19JHOsZ2W39N8kFW9yEI fsUl3koOhVDyw== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 7/8] PM: hibernate: Enter s2idle sleep state before hibernation Date: Fri, 26 Dec 2025 12:26:45 +0200 Message-ID: <20251226102656.6296-8-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674487195.2608645.14321434662587507445@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" Implement the standby states as part of hibernation. Specifically, ensure we are in the inactive state before hibernation entry, and sync the state as active after hibernation resume. In case of a failed hibernation, restore the previous standby state. Signed-off-by: Antheas Kapenekakis --- kernel/power/hibernate.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index af8d07bafe02..85a5ca8f6537 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -787,7 +787,11 @@ static int load_image_and_restore(void) */ int hibernate(void) { +#ifdef CONFIG_SUSPEND + standby_state_t previous_standby; +#endif bool snapshot_test =3D false; + bool powered_down =3D false; unsigned int sleep_flags; int error; =20 @@ -815,6 +819,13 @@ int hibernate(void) } =20 pr_info("hibernation entry\n"); + +#if CONFIG_SUSPEND + /* Enter the standby screen off state in case userspace has not. */ + previous_standby =3D pm_standby_get_state(); + pm_standby_transition(PM_STANDBY_INACTIVE); +#endif + pm_prepare_console(); error =3D pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_H= IBERNATION); if (error) @@ -867,10 +878,12 @@ int hibernate(void) error =3D swsusp_write(flags); swsusp_free(); if (!error) { - if (hibernation_mode =3D=3D HIBERNATION_TEST_RESUME) + if (hibernation_mode =3D=3D HIBERNATION_TEST_RESUME) { snapshot_test =3D true; - else + } else { + powered_down =3D true; power_down(); + } } in_suspend =3D 0; pm_restore_gfp_mask(); @@ -897,6 +910,18 @@ int hibernate(void) Notify: pm_notifier_call_chain(PM_POST_HIBERNATION); Restore: +#if CONFIG_SUSPEND + /* + * If we resumed from S5, we are in the active standby state. However, + * the kernel restored a stale value. Sync it. Otherwise, in e.g., the + * case of a failed hibernation, transition to the previous value. + */ + if (powered_down) + pm_standby_set_state(PM_STANDBY_ACTIVE); + else + pm_standby_transition(previous_standby); +#endif + pm_restore_console(); hibernate_release(); Unlock: --=20 2.52.0 From nobody Sat Feb 7 06:14:51 2026 Received: from relay12.grserver.gr (relay12.grserver.gr [88.99.38.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80DE3316907; Fri, 26 Dec 2025 10:27:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=88.99.38.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744878; cv=none; b=dTOIu9iqns5mInHbP04kkonob9rQEuefwIndvl2N6a65wBqBIvlqyx3kTAzRsxHSmc4o39sETVljLrn9JZAQHGUcQN92dvFCKFIlZ+PcKJi0jhMMHwuiLWQaPVJ0cQNRZHCBHSaiYPDiVCQsZv29C316X06CHD+vbuOG6chGI4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766744878; c=relaxed/simple; bh=GN5FkH2/IWa3xOeAAgG18W6llFXZ1m3UcJYJb7HlAc8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n0RuRxvfSfUerr8QhfRW7Wbj9rgRsNOpYV8LLjCLEb/bzv/+1dsfUTeDoFuv0qVrj60hemd0L4uk6XjtZ6S0s7411th97KPVbkXYBbrhPZtuF2rHUYnNjiRtgsPxGdPL4fPtao1jsj4kBMfdhWC+jHQifMw9OjNziqUvP9rPTUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev; spf=pass smtp.mailfrom=antheas.dev; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b=I9d0Fo5w; arc=none smtp.client-ip=88.99.38.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=antheas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=antheas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=antheas.dev header.i=@antheas.dev header.b="I9d0Fo5w" Received: from relay12 (localhost [127.0.0.1]) by relay12.grserver.gr (Proxmox) with ESMTP id DAC9BBDA4F; Fri, 26 Dec 2025 12:27:54 +0200 (EET) Received: from linux3247.grserver.gr (linux3247.grserver.gr [213.158.90.240]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by relay12.grserver.gr (Proxmox) with ESMTPS id 4C88FBC770; Fri, 26 Dec 2025 12:27:54 +0200 (EET) Received: from antheas-z13 (unknown [IPv6:2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472]) by linux3247.grserver.gr (Postfix) with ESMTPSA id 5EA99200D44; Fri, 26 Dec 2025 12:27:52 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1766744874; bh=94tJEPb5R4/RMYGeb/XvgeZRhmptqhLSfjBLob/O9UU=; h=From:To:Subject; b=I9d0Fo5wUYP2pfVOKr96fFGDjZ8tDfFspm2Z+2C/iNWe/7uAB6YdTQ+AfbmdPF+hc vbzseoWtKPpXWjtiTCwamUaeeboaFJ7LNNdmu/vQ93BFbKrvz6Y7k9Yiw6pid9pPbA UpFtHJujfxXLedP7dnjwIjSIsDnAVj3u6wm3eEvSDW1q189YckCjXjmDLk3sXc3D0G E6WwHDzu3pzs/fmf5+N8eRIVhkISA1W0PiHKXE/QXSJVsjAnYSRTjtKHMwuGKWh+VX /+iIKsrqtZq/LEf4ZqAur+rSX7idBr/8NXU7KrJRGYRt1PU/1wP4CzzTSl61MJtqCs qIdsYyHySS9tw== Authentication-Results: linux3247.grserver.gr; spf=pass (sender IP is 2a02:2149:8a28:c200:ffd7:3bf6:9efd:b472) smtp.mailfrom=lkml@antheas.dev smtp.helo=antheas-z13 Received-SPF: pass (linux3247.grserver.gr: connection is authenticated) From: Antheas Kapenekakis 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 Message-ID: <20251226102656.6296-9-lkml@antheas.dev> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251226102656.6296-1-lkml@antheas.dev> References: <20251226102656.6296-1-lkml@antheas.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-PPP-Message-ID: <176674487387.2608731.11021375007848229427@linux3247.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 1.4.3 at linux3247.grserver.gr X-Virus-Status: Clean Content-Type: text/plain; charset="utf-8" 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 --- 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, struc= t kobj_attribute *attr, =20 power_attr(state); =20 +#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 dur= ing + * resume restores the previous value. + */ +static ssize_t standby_show(struct kobject *kobj, struct kobj_attribute *a= ttr, + char *buf) +{ + unsigned int sleep_flags; + standby_state_t i, curr; + char *s =3D buf; + + sleep_flags =3D lock_system_sleep(); + pm_standby_refresh_states(); + curr =3D pm_standby_get_state(); + unlock_system_sleep(sleep_flags); + + if (curr < 0) + return -EBUSY; + + for (i =3D PM_STANDBY_MIN; i < PM_STANDBY_MAX; i++) + if (standby_states[i]) + s +=3D sprintf(s, curr =3D=3D i ? "[%s] " : "%s ", standby_states[i]); + + if (s !=3D buf) + /* convert the last space to a newline */ + *(s - 1) =3D '\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 =3D memchr(buf, '\n', n); + len =3D p ? p - buf : n; + + for (state =3D PM_STANDBY_MIN; state < PM_STANDBY_MAX; state++) { + const char *label =3D standby_states[state]; + + if (label && len =3D=3D 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 =3D lock_system_sleep(); + pm_standby_refresh_states(); + state =3D decode_standby_state(buf, n); + + if (state >=3D PM_STANDBY_MAX) + return -EINVAL; + + error =3D 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[] =3D { #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, unsigne= d int, char *); extern const char * const pm_labels[]; extern const char *pm_states[]; extern const char *mem_sleep_states[]; +extern const char *standby_states[]; =20 extern int suspend_devices_and_enter(suspend_state_t state); #else /* !CONFIG_SUSPEND */ --=20 2.52.0