From: Antheas Kapenekakis <lkml@antheas.dev>
To: linux-pm@vger.kernel.org
Cc: platform-driver-x86@vger.kernel.org,
dri-devel@lists.freedesktop.org,
Mario Limonciello <mario.limonciello@amd.com>,
Hans de Goede <hdegoede@redhat.com>,
Kyle Gospodnetich <me@kylegospodneti.ch>,
Antheas Kapenekakis <lkml@antheas.dev>
Subject: [RFC 11/13] acpi/x86: s2idle: add quirk table for modern standby delays
Date: Thu, 21 Nov 2024 18:22:36 +0100 [thread overview]
Message-ID: <20241121172239.119590-12-lkml@antheas.dev> (raw)
In-Reply-To: <20241121172239.119590-1-lkml@antheas.dev>
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 <lkml@antheas.dev>
---
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 <linux/acpi.h>
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/delay.h>
#include <linux/suspend.h>
#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;
--
2.47.0
next prev parent reply other threads:[~2024-11-21 17:23 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-21 17:22 [RFC 00/13] acpi/x86: s2idle: implement Modern Standby transition states and expose to userspace Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 01/13] Documentation: PM: Add documentation for S0ix Standby States Antheas Kapenekakis
2024-11-21 18:58 ` Mario Limonciello
2024-11-21 19:11 ` Antheas Kapenekakis
2024-11-21 19:40 ` Mario Limonciello
2024-11-21 20:33 ` Antheas Kapenekakis
2024-11-21 21:08 ` Mario Limonciello
2024-11-21 21:23 ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 02/13] acpi/x86: s2idle: add support for Display Off and Display On callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 03/13] acpi/x86: s2idle: add support for Sleep Entry and Sleep Exit callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 04/13] acpi/x86: s2idle: add support for Turn On Display callback Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 05/13] acpi/x86: s2idle: add modern standby transition function Antheas Kapenekakis
2024-11-21 18:15 ` Mario Limonciello
2024-11-21 18:29 ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 06/13] acpi/x86: s2idle: rename Screen On/Off to Display On/Off Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 07/13] acpi/x86: s2idle: call Display On/Off as part of callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 08/13] acpi/x86: s2idle: rename MS Exit/Entry to Sleep Exit/Entry Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 09/13] acpi/x86: s2idle: call Sleep Entry/Exit as part of callbacks Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 10/13] acpi/x86: s2idle: add Turn On Display and call as part of callback Antheas Kapenekakis
2024-11-21 17:22 ` Antheas Kapenekakis [this message]
2024-11-21 18:04 ` [RFC 11/13] acpi/x86: s2idle: add quirk table for modern standby delays Mario Limonciello
2024-11-21 18:19 ` Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 12/13] platform/x86: asus-wmi: remove Ally (1st gen) and Ally X suspend quirk Antheas Kapenekakis
2024-11-21 17:22 ` [RFC 13/13] PM: standby: Add sysfs attribute for modern standby transitions Antheas Kapenekakis
2024-11-28 11:45 ` Ilpo Järvinen
2024-11-21 17:41 ` [RFC 00/13] acpi/x86: s2idle: implement Modern Standby transition states and expose to userspace Rafael J. Wysocki
2024-12-06 21:37 ` Antheas Kapenekakis
2024-11-22 19:25 ` Xaver Hugl
2024-11-22 23:55 ` Antheas Kapenekakis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241121172239.119590-12-lkml@antheas.dev \
--to=lkml@antheas.dev \
--cc=dri-devel@lists.freedesktop.org \
--cc=hdegoede@redhat.com \
--cc=linux-pm@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=me@kylegospodneti.ch \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox