Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ACPI: PM: s2idle: Check fixed wakeup events in acpi_s2idle_wake()

Commit fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from
waking up the system") overlooked the fact that fixed events can wake
up the system too and broke RTC wakeup from suspend-to-idle as a
result.

Fix this issue by checking the fixed events in acpi_s2idle_wake() in
addition to checking wakeup GPEs and break out of the suspend-to-idle
loop if the status bits of any enabled fixed events are set then.

Fixes: fdde0ff8590b ("ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system")
Reported-and-tested-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Rafael J. Wysocki and committed by
Linus Torvalds
63fb9623 ebe7acad

+53
+45
drivers/acpi/acpica/evevent.c
··· 265 265 handler) (acpi_gbl_fixed_event_handlers[event].context)); 266 266 } 267 267 268 + /******************************************************************************* 269 + * 270 + * FUNCTION: acpi_any_fixed_event_status_set 271 + * 272 + * PARAMETERS: None 273 + * 274 + * RETURN: TRUE or FALSE 275 + * 276 + * DESCRIPTION: Checks the PM status register for active fixed events 277 + * 278 + ******************************************************************************/ 279 + 280 + u32 acpi_any_fixed_event_status_set(void) 281 + { 282 + acpi_status status; 283 + u32 in_status; 284 + u32 in_enable; 285 + u32 i; 286 + 287 + status = acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &in_enable); 288 + if (ACPI_FAILURE(status)) { 289 + return (FALSE); 290 + } 291 + 292 + status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &in_status); 293 + if (ACPI_FAILURE(status)) { 294 + return (FALSE); 295 + } 296 + 297 + /* 298 + * Check for all possible Fixed Events and dispatch those that are active 299 + */ 300 + for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { 301 + 302 + /* Both the status and enable bits must be on for this event */ 303 + 304 + if ((in_status & acpi_gbl_fixed_event_info[i].status_bit_mask) && 305 + (in_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) { 306 + return (TRUE); 307 + } 308 + } 309 + 310 + return (FALSE); 311 + } 312 + 268 313 #endif /* !ACPI_REDUCED_HARDWARE */
+7
drivers/acpi/sleep.c
··· 1006 1006 return true; 1007 1007 1008 1008 /* 1009 + * If the status bit of any enabled fixed event is set, the 1010 + * wakeup is regarded as valid. 1011 + */ 1012 + if (acpi_any_fixed_event_status_set()) 1013 + return true; 1014 + 1015 + /* 1009 1016 * If there are no EC events to process and at least one of the 1010 1017 * other enabled GPEs is active, the wakeup is regarded as a 1011 1018 * genuine one.
+1
include/acpi/acpixf.h
··· 753 753 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) 754 754 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_wakeup_gpes(void)) 755 755 ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_gpe_status_set(void)) 756 + ACPI_HW_DEPENDENT_RETURN_UINT32(u32 acpi_any_fixed_event_status_set(void)) 756 757 757 758 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status 758 759 acpi_get_gpe_device(u32 gpe_index,