From: Furquan Shaikh furquan@google.com
commit c8b1917c8987a6fa3695d479b4d60fbbbc3e537b upstream.
Commit 18996f2db918 ("ACPICA: Events: Stop unconditionally clearing ACPI IRQs during suspend/resume") was added to stop clearing event status bits unconditionally in the system-wide suspend and resume paths. This was done because of an issue with a laptop lid appaering to be closed even when it was used to wake up the system from suspend (see https://bugzilla.kernel.org/show_bug.cgi?id=196249), which happened because event status bits were cleared unconditionally on system resume. Though this change fixed the issue in the resume path, it introduced regressions in a few suspend paths.
First regression was reported and fixed in the S5 entry path by commit fa85015c0d95 ("ACPICA: Clear status of all events when entering S5"). Next regression was reported and fixed for all legacy sleep paths by commit f317c7dc12b7 ("ACPICA: Clear status of all events when entering sleep states"). However, there still is a suspend-to-idle regression, since suspend-to-idle does not follow the legacy sleep paths.
In the suspend-to-idle case, wakeup is enabled as part of device suspend. If the status bits of wakeup GPEs are set when they are enabled, it causes a premature system wakeup to occur.
To address that problem, partially revert commit 18996f2db918 to restore GPE status bits clearing before the GPE is enabled in acpi_ev_enable_gpe().
Fixes: 18996f2db918 ("ACPICA: Events: Stop unconditionally clearing ACPI IRQs during suspend/resume") Signed-off-by: Furquan Shaikh furquan@google.com Cc: 4.17+ stable@vger.kernel.org # 4.17+ [ rjw: Subject & changelog ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/acpi/acpica/evgpe.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -81,8 +81,12 @@ acpi_status acpi_ev_enable_gpe(struct ac
ACPI_FUNCTION_TRACE(ev_enable_gpe);
- /* Enable the requested GPE */ + /* Clear the GPE status */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status);
+ /* Enable the requested GPE */ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); return_ACPI_STATUS(status); }