Merge tag 'nios2-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/lftan...
[sfrench/cifs-2.6.git] / drivers / acpi / sleep.c
index a4327af676fe81948cdb76c3b15786256929ffa8..a6574d62634031ac6e351418b935a333b556b665 100644 (file)
@@ -474,6 +474,7 @@ static void acpi_pm_start(u32 acpi_state)
  */
 static void acpi_pm_end(void)
 {
+       acpi_turn_off_unused_power_resources();
        acpi_scan_lock_release();
        /*
         * This is necessary in case acpi_pm_finish() is not called during a
@@ -662,14 +663,40 @@ static int acpi_freeze_prepare(void)
        acpi_os_wait_events_complete();
        if (acpi_sci_irq_valid())
                enable_irq_wake(acpi_sci_irq);
+
        return 0;
 }
 
+static void acpi_freeze_wake(void)
+{
+       /*
+        * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means
+        * that the SCI has triggered while suspended, so cancel the wakeup in
+        * case it has not been a wakeup event (the GPEs will be checked later).
+        */
+       if (acpi_sci_irq_valid() &&
+           !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq)))
+               pm_system_cancel_wakeup();
+}
+
+static void acpi_freeze_sync(void)
+{
+       /*
+        * Process all pending events in case there are any wakeup ones.
+        *
+        * The EC driver uses the system workqueue, so that one needs to be
+        * flushed too.
+        */
+       acpi_os_wait_events_complete();
+       flush_scheduled_work();
+}
+
 static void acpi_freeze_restore(void)
 {
        acpi_disable_wakeup_devices(ACPI_STATE_S0);
        if (acpi_sci_irq_valid())
                disable_irq_wake(acpi_sci_irq);
+
        acpi_enable_all_runtime_gpes();
 }
 
@@ -681,6 +708,8 @@ static void acpi_freeze_end(void)
 static const struct platform_freeze_ops acpi_freeze_ops = {
        .begin = acpi_freeze_begin,
        .prepare = acpi_freeze_prepare,
+       .wake = acpi_freeze_wake,
+       .sync = acpi_freeze_sync,
        .restore = acpi_freeze_restore,
        .end = acpi_freeze_end,
 };