ACPI / PM: Do not disable wakeup GPEs that have not been enabled
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 12 Dec 2014 21:51:58 +0000 (22:51 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 12 Dec 2014 21:51:58 +0000 (22:51 +0100)
In some cases acpi_device_wakeup() may be called to ensure wakeup
power to be off for a given device even though that device's wakeup
GPE has not been enabled so far.  It calls acpi_disable_gpe() on a
GPE that's not enabled and this causes ACPICA to return the AE_LIMIT
status code from that call which then is reported as an error by the
ACPICA's debug facilities (if enabled).  This may lead to a fair
amount of confusion, so introduce a new ACPI device wakeup flag
to store the wakeup GPE status and avoid disabling wakeup GPEs
that have not been enabled.

Reported-and-tested-by: Venkat Raghavulu <venkat.raghavulu@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/device_pm.c
include/acpi/acpi_bus.h

index 076af814956693e8e65e4a1208455012b1cf6be8..e6ff33ecd784c0b9a33f6e1efa69b5b53acb212f 100644 (file)
@@ -680,13 +680,21 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state,
                if (error)
                        return error;
 
+               if (adev->wakeup.flags.enabled)
+                       return 0;
+
                res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
-               if (ACPI_FAILURE(res)) {
+               if (ACPI_SUCCESS(res)) {
+                       adev->wakeup.flags.enabled = 1;
+               } else {
                        acpi_disable_wakeup_device_power(adev);
                        return -EIO;
                }
        } else {
-               acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+               if (adev->wakeup.flags.enabled) {
+                       acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+                       adev->wakeup.flags.enabled = 0;
+               }
                acpi_disable_wakeup_device_power(adev);
        }
        return 0;
index f34a0835aa4f230f47c57d67e64425d80ba851b7..8de31d472fad2d9018907ff9c49c7ec9b3dbf8f6 100644 (file)
@@ -312,6 +312,7 @@ struct acpi_device_wakeup_flags {
        u8 valid:1;             /* Can successfully enable wakeup? */
        u8 run_wake:1;          /* Run-Wake GPE devices */
        u8 notifier_present:1;  /* Wake-up notify handler has been installed */
+       u8 enabled:1;           /* Enabled for wakeup */
 };
 
 struct acpi_device_wakeup_context {