ACPI: PM: s2idle: Add _Ixx GPE wake indicator support

ACPI 6.6 defines _Ixx indicator objects under \_GPE to mark GPEs that
should remain wake-enabled in s2idle without a _PRW association.

To support them, add new function acpi_setup_ixx_gpes() that looks for
_Ixx objects for all GPEs in the FADT 0/1 blocks and if it finds any, it
marks the corresponding GPE as wake-capable, in which case the GPE is
also enabled so long as it has a handler method because marking it as
wake-capable causes acpi_update_all_gpes() to skip it.

Since the above only needs to be done if suspend-to-idle is enabled,
make acpi_s2idle_setup() call that new function.

For now, this is limited to x86 systems and it assumes that the GPEs
with _Ixx will not cause spurious wakeups to occur while the system
is suspended.

Signed-off-by: Saranya Gopal <saranya.gopal@intel.com>
[ rjw: Added three empty code lines, subject tweak, changelog edits ]
[ rjw: New debug message adjustment ]
Link: https://patch.msgid.link/20260904073844.2740931-1-saranya.gopal@intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Saranya Gopal 2026-09-04 13:08:44 +05:30 committed by Rafael J. Wysocki
parent fd73f4a665
commit 46767b17fd

View File

@ -24,6 +24,34 @@
#ifdef CONFIG_SUSPEND
static void acpi_setup_ixx_gpes(void)
{
acpi_handle gpe_root;
unsigned int i;
char gpe_nr_str[5];
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_GPE", &gpe_root)))
return;
for (i = 0; i <= 0xff; i++) {
scnprintf(gpe_nr_str, sizeof(gpe_nr_str), "_I%02X", i);
if (!acpi_has_method(gpe_root, gpe_nr_str))
continue;
/*
* Enable the GPE if it has a handler method because marking it
* as wake-capable causes acpi_update_all_gpes() to skip it.
*/
if (ACPI_FAILURE(acpi_enable_gpe_cond(NULL, i, ACPI_GPE_DISPATCH_METHOD)))
continue;
acpi_mark_gpe_for_wake(NULL, i);
acpi_set_gpe_wake_mask(NULL, i, ACPI_GPE_ENABLE);
pm_pr_dbg("ACPI: GPE0x%02x armed for wake via %s\n", i, gpe_nr_str);
}
}
static bool sleep_no_lps0 __read_mostly;
module_param(sleep_no_lps0, bool, 0644);
MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface");
@ -649,6 +677,7 @@ void __init acpi_s2idle_setup(void)
{
acpi_scan_add_handler(&lps0_handler);
s2idle_set_ops(&acpi_s2idle_ops_lps0);
acpi_setup_ixx_gpes();
}
int acpi_register_lps0_dev(struct acpi_s2idle_dev_ops *arg)