| From 024aa8732acb7d2503eae43c3fe3504d0a8646d0 Mon Sep 17 00:00:00 2001 |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| Date: Thu, 28 Nov 2019 23:50:40 +0100 |
| Subject: ACPI: PM: s2idle: Rework ACPI events synchronization |
| |
| From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| |
| commit 024aa8732acb7d2503eae43c3fe3504d0a8646d0 upstream. |
| |
| Note that the EC GPE processing need not be synchronized in |
| acpi_s2idle_wake() after invoking acpi_ec_dispatch_gpe(), because |
| that function checks the GPE status and dispatches its handler if |
| need be and the SCI action handler is not going to run anyway at |
| that point. |
| |
| Moreover, it is better to drain all of the pending ACPI events |
| before restoring the working-state configuration of GPEs in |
| acpi_s2idle_restore(), because those events are likely to be related |
| to system wakeup, in which case they will not be relevant going |
| forward. |
| |
| Rework the code to take these observations into account. |
| |
| Tested-by: Kenneth R. Crudup <kenny@panix.com> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/sleep.c | 26 +++++++++++++++++++------- |
| 1 file changed, 19 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/acpi/sleep.c |
| +++ b/drivers/acpi/sleep.c |
| @@ -977,6 +977,16 @@ static int acpi_s2idle_prepare_late(void |
| return 0; |
| } |
| |
| +static void acpi_s2idle_sync(void) |
| +{ |
| + /* |
| + * The EC driver uses the system workqueue and an additional special |
| + * one, so those need to be flushed too. |
| + */ |
| + acpi_ec_flush_work(); |
| + acpi_os_wait_events_complete(); /* synchronize Notify handling */ |
| +} |
| + |
| static bool acpi_s2idle_wake(void) |
| { |
| if (!acpi_sci_irq_valid()) |
| @@ -1021,13 +1031,8 @@ static bool acpi_s2idle_wake(void) |
| * should be missed by canceling the wakeup here. |
| */ |
| pm_system_cancel_wakeup(); |
| - /* |
| - * The EC driver uses the system workqueue and an additional |
| - * special one, so those need to be flushed too. |
| - */ |
| - acpi_os_wait_events_complete(); /* synchronize EC GPE processing */ |
| - acpi_ec_flush_work(); |
| - acpi_os_wait_events_complete(); /* synchronize Notify handling */ |
| + |
| + acpi_s2idle_sync(); |
| |
| /* |
| * The SCI is in the "suspended" state now and it cannot produce |
| @@ -1055,6 +1060,13 @@ static void acpi_s2idle_restore_early(vo |
| |
| static void acpi_s2idle_restore(void) |
| { |
| + /* |
| + * Drain pending events before restoring the working-state configuration |
| + * of GPEs. |
| + */ |
| + acpi_os_wait_events_complete(); /* synchronize GPE processing */ |
| + acpi_s2idle_sync(); |
| + |
| s2idle_wakeup = false; |
| |
| acpi_enable_all_runtime_gpes(); |