From patchwork Thu Nov 21 17:22:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882426 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EE090E6403F for ; Thu, 21 Nov 2024 22:48:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1835C10EA78; Thu, 21 Nov 2024 22:48:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="hakRoM8D"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0A9B810EA03 for ; Thu, 21 Nov 2024 17:28:08 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id ADE042E090EE; Thu, 21 Nov 2024 19:22:44 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209766; bh=aUbHP0EtNdItt/sKM4zDXlLhxrs7moMUJLm1B6QcYMk=; h=From:To:Subject; b=hakRoM8D3hXlR1/1leIIPe2M2+V9M/uID4SexJPvMFiOE43FW1BK0UUS1/cCThZD6 Wira/HO+4lCJprsaPd1cmGwwk1vPlMe9CxLGO4j9qVi3iBl5AlGSIN26mOGdxncJF8 f//9NAIoXLfxZW9MFxQBRuM/T5ybU/G0IsXV1fEQ= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 01/13] Documentation: PM: Add documentation for S0ix Standby States Date: Thu, 21 Nov 2024 18:22:26 +0100 Message-ID: <20241121172239.119590-2-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220976565.3777.6114218929171614883@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add documentation about the S0ix Standby States that will be exposed to userspace as part of this series. Signed-off-by: Antheas Kapenekakis --- .../admin-guide/pm/standby-states.rst | 133 ++++++++++++++++++ Documentation/admin-guide/pm/system-wide.rst | 1 + 2 files changed, 134 insertions(+) create mode 100644 Documentation/admin-guide/pm/standby-states.rst diff --git a/Documentation/admin-guide/pm/standby-states.rst b/Documentation/admin-guide/pm/standby-states.rst new file mode 100644 index 000000000000..96727574312d --- /dev/null +++ b/Documentation/admin-guide/pm/standby-states.rst @@ -0,0 +1,133 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: + +===================== +S0ix Standby States +===================== + +:Copyright: |copy| 2024 Antheas Kapenekakis + +:Author: Antheas Kapenekakis + +With the advent of modern mobile devices, users have become accustomed to instant +wake-up times and always-on connectivity. To meet these expectations, modern +standby was created, which is a standard that allows the platform to seamlessly +transition between an S3-like low-power idle state and a set of low power active +states, where connectivity is maintained, and the system is responsive to user +input. Current x86 hardware supports 5 different standby states, which are: +"Deepest run-time idle platform state" or "DRIPS" (S3-like), "Sleep", "Resume", +"Screen Off", and "Active". + +The system begins in the "Active" state. Either due to user inactivity or +user action (e.g., pressing the power button), it transitions to the "Screen Off" +state. Afterwards, it is free to transition between the "Sleep", "DRIPS", and +"Screen Off" states until user action is received. Once that happens, the system +begins to transition to the "Active" state. From "DRIPS" or "Sleep", it +transitions to "Resume", where the Power Limit (PLx) is restored to its normal +level, to speed up finishing "Sleep". Then, it transitions to "Screen Off". +If on "Screen Off" or after the transition, the display is prepared to turn on +and the system transitions to "Active" alongside turning it on. + +To maintain battery life, in the Windows implementation, the system is allocated +a maximum percentage of battery and time it can use while staying in idle states. +By default, this is 5% of battery or up to 2 days, where the system designer/OEM +is able to tweak these values. If the system exceeds either the battery +percentage or time limit, it enters Hibernation (S4), through a concept +called "Adaptive Hibernate". + + +S0ix Standby States +================================== +The following idle states are supported:: + + ↓→ + + → → ↑ + +.. _s2idle_drips: + +DRIPS +----- + +The "Deepest run-time idle platform state" or "DRIPS" is the lowest power idle +state that the system can enter. It is similar to the S3 state, with the +difference that the system may wake up faster than S3 and due to a larger number +of interrupts (e.g., fingerprint sensor, touchpad, touchscreen). This state +is entered when the system is told to suspend to idle, through conventional +means (see :doc:`sleep states `). The system can only transition +to "DRIPS" while it is in the "Sleep" state. If it is not, the kernel will +automatically transition to the "Sleep" state before beginning the suspend +sequence and restore the previous state afterwards. After the kernel has +suspended, the notifications LSP0 Entry and Exit are used. + +.. _s2idle_sleep: + +Sleep +----- + +The "Sleep" state is a low power idle state where the kernel is fully active. +However, userspace has been partially frozen, particularly desktop applications, +and only essential "value adding" activities are allowed to run. This is not +enforced by the kernel and is the responsibility of userspace (e.g., systemd). +Hardware wise, the Sleep Entry and Exit firmware notifications are fired, which +may lower the Power Limit (PLx), pulse the suspend light, turn off the keyboard +lighting or disable a handheld device's gamepad. This state is associated with +the firmware notifications "Sleep Entry" and "Sleep Exit". + +.. _s2idle_resume: + +Resume +------ + +The "Resume" state is a faux "Sleep" state that is used to fire the Turn On +Display firmware notification when the system is in the "Sleep" state but +intends to turn on the display. It solves the problem of system designers +limiting the Power Limit (PLx) while the system is in the "Sleep" state causing +the system to wake up slower than desired. This firmware notification is used +to restore the normal Power Limit of the system, while having it stay in the +"Sleep" state. As such, the system can only transition to the "Resume" state +while in the "Sleep" state and cannot re-transition to the "Sleep" state +afterwards. + +.. _s2idle_screen_off: + +Screen Off +---------- + +The "Screen Off" state is the state the system enters when all its displays +(virtual or real) turn off. It is used to signify the user is not actively +using the system. The associated firmware notifications of "Display On" and +"Display Off" are used by manufacturers to turn off certain hardware +components that are associated with the display being on, e.g., a handheld +device's controller and RGB. Windows implements a 5-second grace period +before firing this callback when the screen turns off due to inactivity. + +.. _s2idle_active: + +Active +------ + +Finally, the "Active" state is the default state of the system and the one it +has when it is turned on. It is the state where the system is fully operational, +the displays of the device are on, and the user is actively interacting with +the system. + +Basic ``sysfs`` Interface for S0ix Standby transitions +============================================================= + +The file :file:`/sys/power/standby` can be used to transition the system between +the different standby states. The file accepts the following values: ``active``, +``screen_off``, ``sleep``, and ``resume``. File writes will block until the +transition completes. It will return ``-EINVAL`` when asking for 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 pause on the last +error-free state and return an error. The file can be read to retrieve the +current state (and potential ones) using the following format: +``[active] screen_off sleep resume``. The state "DRIPS" is omitted, as it is +entered through the conventional suspend to idle path and userspace will never +be able to see its value due to being suspended. + +Before entering the "Screen Off" state or suspending, it is recommended that +userspace marks all CRTCs as inactive (DPMS). Otherwise, there will be a split +second where the display of the device is on, but the presentation of the system +is inactive (e.g., the power button pulses), which is undesirable. \ No newline at end of file diff --git a/Documentation/admin-guide/pm/system-wide.rst b/Documentation/admin-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 sleep-states + standby-states suspend-flows From patchwork Thu Nov 21 17:22:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3BC98E6403E for ; Thu, 21 Nov 2024 22:47:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 86D6510E41A; Thu, 21 Nov 2024 22:47:38 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="ROQ8fEeb"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 282BD10E145 for ; Thu, 21 Nov 2024 17:28:12 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 173172E09589; Thu, 21 Nov 2024 19:22:49 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209771; bh=0YVrjraYiMF7JFRMsGzYGi+DLsnhBUH9lwvrGzQx40s=; h=From:To:Subject; b=ROQ8fEeb/FgQIikIPcPmun/aLlgmlG34bO+t6bLBdiOpL6ZctiSfIAi2FS8iOqXM/ yKOtdEBqwRB5pvdIb54XUmubFTnXqG18OM/Ln8ct/FIrZcLanIMujuoDsUeVPDv+ZW +d/+BSb87c/h9WXka00b/m8MR1ESpBOLQ5Fjkzuc= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 02/13] acpi/x86: s2idle: add support for Display Off and Display On callbacks Date: Thu, 21 Nov 2024 18:22:27 +0100 Message-ID: <20241121172239.119590-3-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220977021.4257.7217008257458970692@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The Display Off and Display On firmware notifications are meant to signify the system entering a state where the user is not actively interacting with it (i.e., in Windows this state is called "Screen Off" and the system enters it once it turns the screen off e.g., due to inactivity). Currently, these functions are called within the suspend sequence, which causes issues when these notifications interact with e.g., a USB device and makes them unable to be called as part of the screen turning off. This patch adds a set of callbacks to allow calling the Display On/Off notifications outside of the suspend/resume path. Co-developed-by: Mario Limonciello Signed-off-by: Mario Limonciello Signed-off-by: Antheas Kapenekakis --- include/linux/suspend.h | 2 ++ kernel/power/suspend.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index da6ebca3ff77..57c083754e8b 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -132,6 +132,7 @@ struct platform_suspend_ops { }; struct platform_s2idle_ops { + int (*display_off)(void); int (*begin)(void); int (*prepare)(void); int (*prepare_late)(void); @@ -140,6 +141,7 @@ struct platform_s2idle_ops { void (*restore_early)(void); void (*restore)(void); void (*end)(void); + int (*display_on)(void); }; #ifdef CONFIG_SUSPEND diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 09f8397bae15..cded6b9b439b 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -254,6 +254,16 @@ static bool sleep_state_supported(suspend_state_t state) (valid_state(state) && !cxl_mem_active()); } +static int platform_standby_display_off(void) +{ + return s2idle_ops && s2idle_ops->display_off ? s2idle_ops->display_off() : 0; +} + +static int platform_standby_display_on(void) +{ + return s2idle_ops && s2idle_ops->display_on ? s2idle_ops->display_on() : 0; +} + static int platform_suspend_prepare(suspend_state_t state) { return state != PM_SUSPEND_TO_IDLE && suspend_ops->prepare ? From patchwork Thu Nov 21 17:22:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882416 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48FB2E6403B for ; Thu, 21 Nov 2024 22:47:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4405F10E412; Thu, 21 Nov 2024 22:47:37 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="aVltbebO"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id AAF6A10E145 for ; Thu, 21 Nov 2024 17:28:11 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 46D7A2E09693; Thu, 21 Nov 2024 19:22:52 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209773; bh=OzkxDuIjq0abCpdesqahg7f+ZtZjUSV0EPiXaxqA5VM=; h=From:To:Subject; b=aVltbebOkEG9DDsFxDdM93qXN7uF78NYPGeAv7E+f2COeGR61G5yHUhqRrBfwFHLx 1d4w25h8wJAPy8kinDX4F7hzoQTtEIpt+Be1S2DZEXgXfERClk9GowWUac5hcO9OXr w0rKHDmLYDkeyPnAv89RLNamlt7FanVgmuW+icNk= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 03/13] acpi/x86: s2idle: add support for Sleep Entry and Sleep Exit callbacks Date: Thu, 21 Nov 2024 18:22:28 +0100 Message-ID: <20241121172239.119590-4-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220977334.4697.4549620138605508037@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 Signed-off-by: Antheas Kapenekakis --- include/linux/suspend.h | 2 ++ kernel/power/suspend.c | 10 ++++++++++ 2 files changed, 12 insertions(+) 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; From patchwork Thu Nov 21 17:22:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882425 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 578F7E6403B for ; Thu, 21 Nov 2024 22:48:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4582910EA6D; Thu, 21 Nov 2024 22:48:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="IIvpo0H+"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 26C5310E145 for ; Thu, 21 Nov 2024 17:28:11 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 456AE2E09581; Thu, 21 Nov 2024 19:22:54 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209775; bh=dcKL22xxxdJltV2kWHGeg4GmpDoyNBRNF19vSTdCqc8=; h=From:To:Subject; b=IIvpo0H+IHRPyZGFCTTBL5X+SAP/UGRLP8xpQXvgV7aNZN1E83j83aIEYsIH77j7l PBaGTd6rH5z3nNWbg+nEPE3Kcab2et0rc/8IJBEmO3ojS7M3Ix/FJpT+hyiTEWNkRr JMMJ4Hoon4Q+Gdk6V09nVnREUxzNJzN2rJAbub8I= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 04/13] acpi/x86: s2idle: add support for Turn On Display callback Date: Thu, 21 Nov 2024 18:22:29 +0100 Message-ID: <20241121172239.119590-5-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220977544.5013.1531931796239805566@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The Turn On Display callback was introduced in Windows 22H2, to allow devices to resume faster from sleep. Essentially, if the device lowers its power limit (PLx) while it is in the Sleep state, this might lengthen the suspend sequence in an undesirable manner. Therefore, this callback can be used to restore PLx while still remaining in the sleep state. Signed-off-by: Antheas Kapenekakis --- include/linux/suspend.h | 1 + kernel/power/suspend.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 733dffb09b28..01ee64321cda 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -142,6 +142,7 @@ struct platform_s2idle_ops { void (*restore_early)(void); void (*restore)(void); void (*end)(void); + int (*turn_on_display)(void); int (*sleep_exit)(void); int (*display_on)(void); }; diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 3f4bbefa9b82..a42e8514ee7a 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -264,6 +264,13 @@ static int platform_standby_sleep_entry(void) return s2idle_ops && s2idle_ops->sleep_entry ? s2idle_ops->sleep_entry() : 0; } +static int platform_standby_turn_on_display(void) +{ + return s2idle_ops && s2idle_ops->turn_on_display ? + s2idle_ops->turn_on_display() : + 0; +} + static int platform_standby_sleep_exit(void) { return s2idle_ops && s2idle_ops->sleep_exit ? s2idle_ops->sleep_exit() : 0; From patchwork Thu Nov 21 17:22:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882428 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 15B78D743FE for ; Thu, 21 Nov 2024 22:48:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E9F2910EA7B; Thu, 21 Nov 2024 22:48:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="Q/xfjQMG"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8AC4110E145 for ; Thu, 21 Nov 2024 17:33:07 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id DA5DE2E09594; Thu, 21 Nov 2024 19:22:55 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209777; bh=etxEsp1/Zp5Onht50q+cVfkXXC1E1c/Mq9gluG3R0+Y=; h=From:To:Subject; b=Q/xfjQMGKhI+wS4gKp2RDRSpmMznb6ZeWSyecWYb0qRtfi9t2H6CoDW61Ukbxh9F0 r4NgnRt7qN5Z8M507IiT2dWiSOdE/+4aj/pLCawDXG06ZYQ7qTqGwsGFKidtDymIdZ FlhnyGO9t4irzhrXd6Nf3/ZpDbLcBXw4HXm+UdBQ= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 05/13] acpi/x86: s2idle: add modern standby transition function Date: Thu, 21 Nov 2024 18:22:30 +0100 Message-ID: <20241121172239.119590-6-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220977702.5388.1203506289428423876@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add a new function to transition modern standby states and call it as part of the suspend sequence to make sure it begins under the Modern Standby "Sleep" state. Signed-off-by: Antheas Kapenekakis --- include/linux/suspend.h | 11 ++++ kernel/power/power.h | 1 + kernel/power/suspend.c | 127 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 01ee64321cda..b8fe781d8026 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -40,6 +40,15 @@ typedef int __bitwise suspend_state_t; #define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) +typedef int __bitwise standby_state_t; + +#define PM_STANDBY_ACTIVE ((__force standby_state_t) 0) +#define PM_STANDBY_SCREEN_OFF ((__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) + /** * struct platform_suspend_ops - Callbacks for managing platform dependent * system sleep states. @@ -281,6 +290,8 @@ extern void arch_suspend_enable_irqs(void); extern int pm_suspend(suspend_state_t state); extern bool sync_on_suspend_enabled; +extern int pm_standby_transition(standby_state_t state); +extern int pm_standby_state(void); #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL diff --git a/kernel/power/power.h b/kernel/power/power.h index de0e6b1077f2..4ee067cd0d4d 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -207,6 +207,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 */ diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index a42e8514ee7a..1865db71a0c2 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -45,12 +45,21 @@ static const char * const mem_sleep_labels[] = { [PM_SUSPEND_MEM] = "deep", }; const char *mem_sleep_states[PM_SUSPEND_MAX]; +static const char * const standby_labels[] = { + [PM_STANDBY_ACTIVE] = "active", + [PM_STANDBY_SCREEN_OFF] = "screen_off", + [PM_STANDBY_SLEEP] = "sleep", + [PM_STANDBY_RESUME] = "resume", +}; +const char *standby_states[PM_STANDBY_MAX]; suspend_state_t mem_sleep_current = PM_SUSPEND_TO_IDLE; suspend_state_t mem_sleep_default = PM_SUSPEND_MAX; suspend_state_t pm_suspend_target_state; EXPORT_SYMBOL_GPL(pm_suspend_target_state); +standby_state_t standby_current = PM_STANDBY_ACTIVE; + unsigned int pm_suspend_global_flags; EXPORT_SYMBOL_GPL(pm_suspend_global_flags); @@ -188,6 +197,16 @@ void __init pm_states_init(void) * initialize mem_sleep_states[] accordingly here. */ mem_sleep_states[PM_SUSPEND_TO_IDLE] = mem_sleep_labels[PM_SUSPEND_TO_IDLE]; + /* All systems support the "active" state. */ + standby_states[PM_STANDBY_ACTIVE] = standby_labels[PM_STANDBY_ACTIVE]; + /* + * Not all systems support these states, where they will have increased + * power consumption. If deemed necessary, they should be gated to not + * mislead userspace. + */ + standby_states[PM_STANDBY_SCREEN_OFF] = standby_labels[PM_STANDBY_SCREEN_OFF]; + standby_states[PM_STANDBY_SLEEP] = standby_labels[PM_STANDBY_SLEEP]; + standby_states[PM_STANDBY_RESUME] = standby_labels[PM_STANDBY_RESUME]; } static int __init mem_sleep_default_setup(char *str) @@ -354,6 +373,108 @@ static bool platform_suspend_again(suspend_state_t state) suspend_ops->suspend_again() : false; } +static int platform_standby_transition_internal(standby_state_t state) +{ + int error; + + if (state == standby_current) + return 0; + if (state > PM_STANDBY_MAX) + return -EINVAL; + + 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 == PM_STANDBY_RESUME) { + if (standby_current != PM_STANDBY_SLEEP) + return -EINVAL; + standby_current = PM_STANDBY_RESUME; + return platform_standby_turn_on_display(); + } + + /* + * 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", + * were promised a transition to "Screen Off" or "Active". + */ + if (standby_current == PM_STANDBY_RESUME && state == PM_STANDBY_SLEEP) + return -EINVAL; + + /* Resume is the Sleep state logic-wise. */ + if (standby_current == PM_STANDBY_RESUME) + standby_current = PM_STANDBY_SLEEP; + + if (standby_current < state) { + for (; standby_current < state; standby_current++) { + switch (standby_current + 1) { + case PM_STANDBY_SCREEN_OFF: + error = platform_standby_display_off(); + break; + case PM_STANDBY_SLEEP: + error = platform_standby_sleep_entry(); + break; + } + + if (error) + return error; + } + } else if (standby_current > state) { + for (; standby_current > state; standby_current--) { + switch (standby_current) { + case PM_STANDBY_SLEEP: + error = platform_standby_sleep_exit(); + break; + case PM_STANDBY_SCREEN_OFF: + error = platform_standby_display_on(); + break; + } + + if (error) + return error; + } + } + + return 0; +} + +/** + * pm_standby_transition - Transition between Modern Standby states + * + * Fires the appropriate firmware notifications to transition to the requested + * state. Returns an error if the transition fails. The function does not + * rollback. It is up to userspace to handle the error and re-transition when + * appropriate. + */ +int pm_standby_transition(standby_state_t state) +{ + unsigned int sleep_flags; + int error; + + sleep_flags = lock_system_sleep(); + error = platform_standby_transition_internal(state); + unlock_system_sleep(sleep_flags); + + return error; +} +EXPORT_SYMBOL_GPL(pm_standby_transition); + +/** + * pm_standby_state - Returns the current standby state + */ +int pm_standby_state(void) +{ + unsigned int sleep_flags; + int state; + + sleep_flags = lock_system_sleep(); + state = standby_current; + unlock_system_sleep(sleep_flags); + + return state; +} +EXPORT_SYMBOL_GPL(pm_standby_state); + #ifdef CONFIG_PM_DEBUG static unsigned int pm_test_delay = 5; module_param(pm_test_delay, uint, 0644); @@ -586,6 +707,7 @@ static void suspend_finish(void) static int enter_state(suspend_state_t state) { int error; + standby_state_t standby_prior; trace_suspend_resume(TPS("suspend_enter"), state, true); if (state == PM_SUSPEND_TO_IDLE) { @@ -601,6 +723,9 @@ static int enter_state(suspend_state_t state) if (!mutex_trylock(&system_transition_mutex)) return -EBUSY; + standby_prior = standby_current; + platform_standby_transition_internal(PM_STANDBY_SLEEP); + if (state == PM_SUSPEND_TO_IDLE) s2idle_begin(); @@ -630,6 +755,8 @@ static int enter_state(suspend_state_t state) pm_pr_dbg("Finishing wakeup.\n"); suspend_finish(); Unlock: + platform_standby_transition_internal(standby_prior); + mutex_unlock(&system_transition_mutex); return error; } From patchwork Thu Nov 21 17:22:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882417 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5467CE6403B for ; Thu, 21 Nov 2024 22:47:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BF24910E416; Thu, 21 Nov 2024 22:47:37 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="jyk0mZFC"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4A15B10EA03 for ; Thu, 21 Nov 2024 17:33:10 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 849D92E0963A; Thu, 21 Nov 2024 19:22:57 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209778; bh=nIjR2p0YcBkL2caLKP7kGbNnMWaOSQpHKmr9UXjFGMg=; h=From:To:Subject; b=jyk0mZFCN3AlzgxqXnHx9+sIXZY525QfHl6fWv/1HzQ3MdLpxMcL3qRBNazW0xyGd P3vQ1Jlt3BB9JiWHSYdGNwdnsSVSQ8/Eyd2qdq7Pu3UDxK7PDr8ELj5gIabHiW/f/I t4XZVGMzjYIN0uHLtstsgD2ZqAhd0xwwMyXvr9F4= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 06/13] acpi/x86: s2idle: rename Screen On/Off to Display On/Off Date: Thu, 21 Nov 2024 18:22:31 +0100 Message-ID: <20241121172239.119590-7-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220977865.5739.5786625115036377066@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Microsoft and Intel use the term "Display" to refer to the _DSM 3,4 calls and the term "Screen" for the state ("Screen Off"). Currently, the code uses "Screen On/Off" to name the variables, which is about to become confusing as they become callbacks. To prepare for that, rename the variables to "Display On/Off". Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index dd0b40b9bbe8..7391f87f3aa0 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -39,8 +39,8 @@ static const struct acpi_device_id lps0_device_ids[] = { #define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" #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 @@ -50,8 +50,8 @@ static const struct acpi_device_id lps0_device_ids[] = { #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 static acpi_handle lps0_device_handle; static guid_t lps0_dsm_guid; @@ -361,10 +361,10 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned 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: @@ -376,10 +376,10 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned int state) } } 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: @@ -552,12 +552,12 @@ int acpi_s2idle_prepare_late(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); 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); /* LPS0 entry */ @@ -626,12 +626,12 @@ void acpi_s2idle_restore_early(void) /* 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); } From patchwork Thu Nov 21 17:22:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882420 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6E443E64025 for ; Thu, 21 Nov 2024 22:47:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 114D410E41F; Thu, 21 Nov 2024 22:47:38 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="FKI2hFuo"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4143D10E145 for ; Thu, 21 Nov 2024 17:33:10 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 301052E0966E; Thu, 21 Nov 2024 19:22:59 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209781; bh=ciKMesMP9Mc1IdOCWc4ppsKpGwJlPYfRDo95aaXXzt4=; h=From:To:Subject; b=FKI2hFuoBYe4NdD4JqhxeV0tCjKnTThOqV+7FE+B+xeZTusiOjcSkPCT0kQAoOhjp Umwj3OUKc85zGq7E0PifEkeWWyMu+CxfaCV/i6Y7UaE+rxxfAjZro7qVECCzKMYIiU ZXS1EMM40U4hPZ0BcG3tCYICee/MyCUW9uRrcS54= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 07/13] acpi/x86: s2idle: call Display On/Off as part of callbacks Date: Thu, 21 Nov 2024 18:22:32 +0100 Message-ID: <20241121172239.119590-8-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220978051.6005.3661749764522674078@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Move the Display On/Off notifications into dedicated callbacks that gate the ACPI mutex, so they can be called outside of the suspend path. Co-developed-by: Mario Limonciello Signed-off-by: Mario Limonciello Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 67 +++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 7391f87f3aa0..8b39e3b12ec0 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -60,6 +60,7 @@ static int lps0_dsm_func_mask; static guid_t lps0_dsm_guid_microsoft; static int lps0_dsm_func_mask_microsoft; static int lps0_dsm_state; +static bool lsp0_dsm_in_display_off; /* Device constraint entry structure */ struct lpi_device_info { @@ -539,17 +540,18 @@ static struct acpi_scan_handler lps0_handler = { .attach = lps0_device_attach, }; -int acpi_s2idle_prepare_late(void) +static int acpi_s2idle_display_off(void) { - struct acpi_s2idle_dev_ops *handler; - if (!lps0_device_handle || sleep_no_lps0) return 0; - if (pm_debug_messages_on) - lpi_check_constraints(); + if (WARN_ON(lsp0_dsm_in_display_off)) + return -EINVAL; + + lsp0_dsm_in_display_off = true; + acpi_scan_lock_acquire(); - /* Screen off */ + /* Display off */ if (lps0_dsm_func_mask > 0) acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ? ACPI_LPS0_DISPLAY_OFF_AMD : @@ -560,6 +562,47 @@ int acpi_s2idle_prepare_late(void) acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_OFF, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); + acpi_scan_lock_release(); + + return 0; +} + +static int acpi_s2idle_display_on(void) +{ + if (!lps0_device_handle || sleep_no_lps0) + return 0; + + if (WARN_ON(!lsp0_dsm_in_display_off)) + return -EINVAL; + + lsp0_dsm_in_display_off = false; + acpi_scan_lock_acquire(); + + /* Display on */ + 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); + 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); + + acpi_scan_lock_release(); + + return 0; +} + +int acpi_s2idle_prepare_late(void) +{ + struct acpi_s2idle_dev_ops *handler; + + if (!lps0_device_handle || sleep_no_lps0) + return 0; + + if (pm_debug_messages_on) + lpi_check_constraints(); + /* LPS0 entry */ if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd()) acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD, @@ -623,19 +666,10 @@ void acpi_s2idle_restore_early(void) acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_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, - 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); } static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { + .display_off = acpi_s2idle_display_off, .begin = acpi_s2idle_begin, .prepare = acpi_s2idle_prepare, .prepare_late = acpi_s2idle_prepare_late, @@ -644,6 +678,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, + .display_on = acpi_s2idle_display_on, }; void __init acpi_s2idle_setup(void) From patchwork Thu Nov 21 17:22:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882424 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A06BE6403C for ; Thu, 21 Nov 2024 22:48:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D890010EA76; Thu, 21 Nov 2024 22:48:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="SaEUrQ6Z"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8E1B210EA03 for ; Thu, 21 Nov 2024 17:33:07 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 9893F2E09694; Thu, 21 Nov 2024 19:23:01 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209783; bh=++PgO6Kf7fkqqQwS6ej9C+2J5H1QoRjUhk8jT24SeC4=; h=From:To:Subject; b=SaEUrQ6ZP4g3tPbHCR0lsNIrNUry5Nwj6a42MeUZPaXjHKivRFFRv88E8q+BaoP17 Ggb8H8Ze3xvEe6KOnRyp/TC76KYEboar5/UmtvjUWDaf26kgBf+hkU6ZP9xe/8YVYr LVKailruCXEP8PmgmtbdkTodaUzLU4zDPioFgYo0= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 08/13] acpi/x86: s2idle: rename MS Exit/Entry to Sleep Exit/Entry Date: Thu, 21 Nov 2024 18:22:33 +0100 Message-ID: <20241121172239.119590-9-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220978286.6491.2438004784289973570@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Microsoft refers to the _DSMs 7,8 as "Sleep Entry" and "Sleep Exit". Currently, the code uses "MS Entry/Exit" to name the variables, which is confusing as it could either mean "Modern Standby" or "Microsoft" and is not representative of the state. Rename as part of converting it into a transition. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 8b39e3b12ec0..49dcbdea903a 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -43,8 +43,8 @@ static const struct acpi_device_id lps0_device_ids[] = { #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 /* AMD */ #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" @@ -370,10 +370,10 @@ static const char *acpi_sleep_dsm_state_to_str(unsigned int state) 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) { @@ -610,7 +610,7 @@ int acpi_s2idle_prepare_late(void) 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); @@ -663,7 +663,7 @@ void acpi_s2idle_restore_early(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); } } From patchwork Thu Nov 21 17:22:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4D03CE6403B for ; Thu, 21 Nov 2024 22:48:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AB1D310EA7A; Thu, 21 Nov 2024 22:48:01 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="t47zSLsQ"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9E4E610EA07 for ; Thu, 21 Nov 2024 17:33:07 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 470F52E096A9; Thu, 21 Nov 2024 19:23:04 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209788; bh=qGjHS8GQ4N3CJVQ4zNZrdwaBwtKD2iqsG4bJWaOXvl0=; h=From:To:Subject; b=t47zSLsQqqK0XuiT9GSfSTCmhFjdtjU7Ug6E1u4/k50n4tUITpIjWvFQyPsb09OkZ kh1zM2Oj7eS9FBw3yBAcgE8lDVbE4zkSDmcTC7QKjcezjEOZVpONEGW1OF9TENzmDB CLGRObLzDRAIwiRob2+jMeJYnCtVZ/Y56BphfWhY= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 09/13] acpi/x86: s2idle: call Sleep Entry/Exit as part of callbacks Date: Thu, 21 Nov 2024 18:22:34 +0100 Message-ID: <20241121172239.119590-10-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220978571.7825.3175429476405251822@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Move the Sleep Entry/Exit notifications outside the suspend sequence, with their own ACPI lock, as was done for Display On/Off. Suggested-by: Mario Limonciello Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 57 ++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index 49dcbdea903a..bdc2cc8d4994 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -61,6 +61,7 @@ static guid_t lps0_dsm_guid_microsoft; static int lps0_dsm_func_mask_microsoft; static int lps0_dsm_state; static bool lsp0_dsm_in_display_off; +static bool lsp0_dsm_in_sleep; /* Device constraint entry structure */ struct lpi_device_info { @@ -567,6 +568,48 @@ static int acpi_s2idle_display_off(void) return 0; } +static int acpi_s2idle_sleep_entry(void) +{ + if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0) + return 0; + + if (WARN_ON(lsp0_dsm_in_sleep)) + return -EINVAL; + + lsp0_dsm_in_sleep = true; + acpi_scan_lock_acquire(); + + /* Modern Standby 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); + + acpi_scan_lock_release(); + + return 0; +} + +static int acpi_s2idle_sleep_exit(void) +{ + if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0) + return 0; + + if (WARN_ON(!lsp0_dsm_in_sleep)) + return -EINVAL; + + lsp0_dsm_in_sleep = false; + acpi_scan_lock_acquire(); + + /* Modern Standby 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); + + acpi_scan_lock_release(); + + return 0; +} + static int acpi_s2idle_display_on(void) { if (!lps0_device_handle || sleep_no_lps0) @@ -608,13 +651,9 @@ int acpi_s2idle_prepare_late(void) 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); + if (lps0_dsm_func_mask_microsoft > 0) 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, @@ -659,17 +698,14 @@ void acpi_s2idle_restore_early(void) ACPI_LPS0_EXIT, lps0_dsm_func_mask, lps0_dsm_guid); - if (lps0_dsm_func_mask_microsoft > 0) { + 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); - } } static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = { .display_off = acpi_s2idle_display_off, + .sleep_entry = acpi_s2idle_sleep_entry, .begin = acpi_s2idle_begin, .prepare = acpi_s2idle_prepare, .prepare_late = acpi_s2idle_prepare_late, @@ -678,6 +714,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, + .sleep_exit = acpi_s2idle_sleep_exit, .display_on = acpi_s2idle_display_on, }; From patchwork Thu Nov 21 17:22:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882419 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E3A7AE64039 for ; Thu, 21 Nov 2024 22:47:47 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1AF0010E420; Thu, 21 Nov 2024 22:47:38 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="lvi8NWAr"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4B19710EA03 for ; Thu, 21 Nov 2024 17:33:09 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 0F1152E0952F; Thu, 21 Nov 2024 19:23:08 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209791; bh=md6zaJta8omWGAdQeUBLLs46yHXPjdxLdPWorE9Bt7o=; h=From:To:Subject; b=lvi8NWArex8mogvPYZwjq7HnYAXitC8yxOhHcfQRD2ifF79HVpyy8g+xDQqkRIMll RtRM3KxAFksXLnCiQLP7P3bv5SS5hfHhNWFRifO/57XNG7JrBlDKSDUWiU/J+HtQH9 ghJZvehM74sRU2wE5lMiENmFtnuCQ/nZGkrm79Jg= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 10/13] acpi/x86: s2idle: add Turn On Display and call as part of callback Date: Thu, 21 Nov 2024 18:22:35 +0100 Message-ID: <20241121172239.119590-11-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220979049.9411.6636007944859871917@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The Turn On Display callback was introduced in Windows 22H2, to allow devices to resume faster from sleep. Essentially, if the device lowers its power limit (PLx) while it is in the Sleep state, this might lengthen the suspend sequence in an undesirable manner. Implement this callback, which corresponds to Modern Standby Firmware notification (_DSM) 9. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index bdc2cc8d4994..d389c57d2963 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -45,6 +45,7 @@ static const struct acpi_device_id lps0_device_ids[] = { #define ACPI_LPS0_EXIT 6 #define ACPI_LPS0_SLEEP_ENTRY 7 #define ACPI_LPS0_SLEEP_EXIT 8 +#define ACPI_LPS0_TURN_ON_DISPLAY 9 /* AMD */ #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721" @@ -375,6 +376,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) { @@ -589,6 +592,29 @@ static int acpi_s2idle_sleep_entry(void) return 0; } +static int acpi_s2idle_turn_on_display(void) +{ + if (!lps0_device_handle || sleep_no_lps0 || + lps0_dsm_func_mask_microsoft <= 0) + return 0; + + /* This call is only valid while we are in a sleep state */ + if (WARN_ON(!lsp0_dsm_in_sleep)) + return -EINVAL; + + acpi_scan_lock_acquire(); + + /* Modern Standby Turn On Display */ + 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); + + acpi_scan_lock_release(); + + return 0; +} + static int acpi_s2idle_sleep_exit(void) { if (!lps0_device_handle || sleep_no_lps0 || lps0_dsm_func_mask_microsoft <= 0) @@ -714,6 +740,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, + .turn_on_display = acpi_s2idle_turn_on_display, .sleep_exit = acpi_s2idle_sleep_exit, .display_on = acpi_s2idle_display_on, }; From patchwork Thu Nov 21 17:22:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882418 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4B8CFE64025 for ; Thu, 21 Nov 2024 22:47:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C175210E417; Thu, 21 Nov 2024 22:47:37 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="0PNMkJS1"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9749410EA05 for ; Thu, 21 Nov 2024 17:33:07 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id 4E5922E096A7; Thu, 21 Nov 2024 19:23:11 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209795; bh=4jRR2+wST/8adxHo9mGYLxXc0Y5dG1aBSyRjSI/GHAs=; h=From:To:Subject; b=0PNMkJS11Glj7sDgMZW+CBArPd72mWvMrsy7n+i8C3PxLZGZV7lWCceW0JRd+yP6Q rlmL1+O4O9W3GbMON/UGn+vosK4prapaKVWmyVoqlZ5KKEasL6OPmR/kUOcGaBk624 9kuqJnJdzwFA6ZyTjQjSIJZOZ1Bjt9pbLRR7s/mE= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 11/13] acpi/x86: s2idle: add quirk table for modern standby delays Date: Thu, 21 Nov 2024 18:22:36 +0100 Message-ID: <20241121172239.119590-12-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220979320.9660.4079469559487333899@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Unfortunately, some modern standby systems, including the ROG Ally, rely on a delay between modern standby transitions. Add a quirk table for introducing delays between modern standby transitions, and quirk the ROG Ally on "Display Off", which needs a bit of time to turn off its controllers prior to suspending. Signed-off-by: Antheas Kapenekakis --- drivers/acpi/x86/s2idle.c | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index d389c57d2963..504e6575d7ad 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "../sleep.h" @@ -91,11 +92,50 @@ struct lpi_device_constraint_amd { int min_dstate; }; +struct s2idle_delay_quirks { + int delay_display_off; + int delay_sleep_entry; + int delay_sleep_exit; + int delay_display_on; +}; + +/* + * The ROG Ally series disconnects its controllers on Display Off and performs + * a fancy shutdown sequence, which requires around half a second to complete. + * If the power is cut earlier by entering it into D3, the original Ally unit + * might not disconnect its XInput MCU, causing excess battery drain, and the + * Ally X will make the controller restart post-suspend. In addition, the EC + * of the device rarely (1/20 attempts) may get stuck asserting PROCHOT after + * suspend (for various reasons), so split the delay between Display Off and + * Sleep Entry. + */ +static const struct s2idle_delay_quirks rog_ally_quirks = { + .delay_display_off = 350, + .delay_sleep_entry = 150, +}; + +static const struct dmi_system_id s2idle_delay_quirks[] = { + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "RC71L"), + }, + .driver_data = (void *)&rog_ally_quirks + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "RC72L"), + }, + .driver_data = (void *)&rog_ally_quirks + }, + {} +}; + static LIST_HEAD(lps0_s2idle_devops_head); static struct lpi_constraints *lpi_constraints_table; static int lpi_constraints_table_size; static int rev_id; +struct s2idle_delay_quirks *delay_quirks; #define for_each_lpi_constraint(entry) \ for (int i = 0; \ @@ -566,6 +606,9 @@ static int acpi_s2idle_display_off(void) acpi_sleep_run_lps0_dsm(ACPI_LPS0_DISPLAY_OFF, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); + if (delay_quirks && delay_quirks->delay_display_off) + msleep(delay_quirks->delay_display_off); + acpi_scan_lock_release(); return 0; @@ -587,6 +630,9 @@ static int acpi_s2idle_sleep_entry(void) acpi_sleep_run_lps0_dsm(ACPI_LPS0_SLEEP_ENTRY, lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft); + if (delay_quirks && delay_quirks->delay_sleep_entry) + msleep(delay_quirks->delay_sleep_entry); + acpi_scan_lock_release(); return 0; @@ -627,6 +673,9 @@ static int acpi_s2idle_sleep_exit(void) acpi_scan_lock_acquire(); /* Modern Standby Sleep Exit */ + if (delay_quirks && delay_quirks->delay_sleep_exit) + msleep(delay_quirks->delay_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); @@ -648,6 +697,9 @@ static int acpi_s2idle_display_on(void) acpi_scan_lock_acquire(); /* Display on */ + if (delay_quirks && delay_quirks->delay_display_on) + msleep(delay_quirks->delay_display_on); + 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); @@ -760,6 +812,10 @@ int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg) sleep_flags = lock_system_sleep(); list_add(&arg->list_node, &lps0_s2idle_devops_head); + const struct dmi_system_id *s2idle_sysid = dmi_first_match( + s2idle_delay_quirks + ); + delay_quirks = s2idle_sysid ? s2idle_sysid->driver_data : NULL; unlock_system_sleep(sleep_flags); return 0; From patchwork Thu Nov 21 17:22:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882422 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 21FBBE6403B for ; Thu, 21 Nov 2024 22:47:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E93410E424; Thu, 21 Nov 2024 22:47:39 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="VO3CrKUA"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4813310E145 for ; Thu, 21 Nov 2024 17:33:09 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id C2D8E2E096AA; Thu, 21 Nov 2024 19:23:16 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209806; bh=ArI/jn7jjAjrFDZ6mHlYYhyyOVKap9QHSt5gxWhpUFA=; h=From:To:Subject; b=VO3CrKUAqMscIodeyPF5b7IKRSTjmVZsyenBsWxvzrZCQZjY8NSC8APGFhBH5/spl 7/VnQhkpp2UsXKjzqrfi8bxAxNAgwBK2RwnN72QrGwHPKmPBWdIisB562TKGrpyDsc /lQMDrAzkIP8+usfB/y/bAh2WUdAK/LifjyxPi6U= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 12/13] platform/x86: asus-wmi: remove Ally (1st gen) and Ally X suspend quirk Date: Thu, 21 Nov 2024 18:22:37 +0100 Message-ID: <20241121172239.119590-13-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220980010.10092.9561175062432005585@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" By moving the Display On/Off calls outside of the suspend sequence and introducing a slight delay after Display Off, the ROG Ally controller functions exactly as it does in Windows. Therefore, remove the quirk that fixed the controller only when the mcu_powersave attribute was disabled, while adding a large amount of delay to the suspend and wake process. Reviewed-by: Mario Limonciello Signed-off-by: Antheas Kapenekakis --- drivers/platform/x86/asus-wmi.c | 54 --------------------------------- 1 file changed, 54 deletions(-) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index abdca3f05c5c..73a2ab214f56 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -142,29 +142,10 @@ module_param(fnlock_default, bool, 0444); #define ASUS_MINI_LED_2024_STRONG 0x01 #define ASUS_MINI_LED_2024_OFF 0x02 -/* Controls the power state of the USB0 hub on ROG Ally which input is on */ -#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" -/* 300ms so far seems to produce a reliable result on AC and battery */ -#define ASUS_USB0_PWR_EC0_CSEE_WAIT 1500 - static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; static int throttle_thermal_policy_write(struct asus_wmi *); -static const struct dmi_system_id asus_ally_mcu_quirk[] = { - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "RC71L"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_BOARD_NAME, "RC72L"), - }, - }, - { }, -}; - static bool ashs_present(void) { int i = 0; @@ -274,9 +255,6 @@ struct asus_wmi { u32 tablet_switch_dev_id; bool tablet_switch_inverted; - /* The ROG Ally device requires the MCU USB device be disconnected before suspend */ - bool ally_mcu_usb_switch; - enum fan_type fan_type; enum fan_type gpu_fan_type; enum fan_type mid_fan_type; @@ -4770,8 +4748,6 @@ static int asus_wmi_add(struct platform_device *pdev) asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU); asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU); asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); - asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) - && dmi_check_system(asus_ally_mcu_quirk); if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE)) asus->mini_led_dev_id = ASUS_WMI_DEVID_MINI_LED_MODE; @@ -4962,34 +4938,6 @@ static int asus_hotk_resume(struct device *device) return 0; } -static int asus_hotk_resume_early(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - - if (asus->ally_mcu_usb_switch) { - /* sleep required to prevent USB0 being yanked then reappearing rapidly */ - if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8))) - dev_err(device, "ROG Ally MCU failed to connect USB dev\n"); - else - msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); - } - return 0; -} - -static int asus_hotk_prepare(struct device *device) -{ - struct asus_wmi *asus = dev_get_drvdata(device); - - if (asus->ally_mcu_usb_switch) { - /* sleep required to ensure USB0 is disabled before sleep continues */ - if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7))) - dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n"); - else - msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); - } - return 0; -} - static int asus_hotk_restore(struct device *device) { struct asus_wmi *asus = dev_get_drvdata(device); @@ -5034,8 +4982,6 @@ static const struct dev_pm_ops asus_pm_ops = { .thaw = asus_hotk_thaw, .restore = asus_hotk_restore, .resume = asus_hotk_resume, - .resume_early = asus_hotk_resume_early, - .prepare = asus_hotk_prepare, }; /* Registration ***************************************************************/ From patchwork Thu Nov 21 17:22:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antheas Kapenekakis X-Patchwork-Id: 13882429 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C34A3E6403D for ; Thu, 21 Nov 2024 22:48:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0101010EA7C; Thu, 21 Nov 2024 22:48:02 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=antheas.dev header.i=@antheas.dev header.b="xd5Zm672"; dkim-atps=neutral Received: from linux1587.grserver.gr (linux1587.grserver.gr [185.138.42.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id A225610EA08 for ; Thu, 21 Nov 2024 17:33:07 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2a05:f6c2:511b:0:cbc0:999f:73ad:33bd]) by linux1587.grserver.gr (Postfix) with ESMTPSA id AAAE32E096A8; Thu, 21 Nov 2024 19:23:26 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=antheas.dev; s=default; t=1732209814; bh=0f+2vUNiJNBCr2npgGT+5C+NFvaobl1gc8LB0xDB8Io=; h=From:To:Subject; b=xd5Zm672kx6WPxxwdIdOopLw247otKLGUSlYgc39zBytVDs1dqLf6PnKD44ji7rMJ tZaXea3xm/nZvvo8YlbExpNPAXZjOkbWK/d0lNEFSt/EziDuGBpZSPnow+Wp/lyly7 jJ/McVF4SCNYb8GmqCpBeVoLdvOM0gI5PtrsK5kU= Authentication-Results: linux1587.grserver.gr; spf=pass (sender IP is 2a05:f6c2:511b:0:cbc0:999f:73ad:33bd) smtp.mailfrom=lkml@antheas.dev smtp.helo=localhost.localdomain Received-SPF: pass (linux1587.grserver.gr: connection is authenticated) From: Antheas Kapenekakis To: linux-pm@vger.kernel.org Cc: platform-driver-x86@vger.kernel.org, dri-devel@lists.freedesktop.org, Mario Limonciello , Hans de Goede , Kyle Gospodnetich , Antheas Kapenekakis Subject: [RFC 13/13] PM: standby: Add sysfs attribute for modern standby transitions Date: Thu, 21 Nov 2024 18:22:38 +0100 Message-ID: <20241121172239.119590-14-lkml@antheas.dev> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev> References: <20241121172239.119590-1-lkml@antheas.dev> MIME-Version: 1.0 X-PPP-Message-ID: <173220981281.10560.4859672454396129529@linux1587.grserver.gr> X-PPP-Vhost: antheas.dev X-Virus-Scanned: clamav-milter 0.103.11 at linux1587.grserver.gr X-Virus-Status: Clean X-Mailman-Approved-At: Thu, 21 Nov 2024 22:47:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 --- 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 +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 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; + 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]); + + 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) +{ + 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; +} + +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,