diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-12-12 16:51:58 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-12-12 16:51:58 -0500 |
commit | 175f8e2650f7ca6b33d338be3ccc1c00e89594ea (patch) | |
tree | 7a81830a3fd4a2da4db45d2dd791493a2ac6d5de | |
parent | c52fa70c79acbb1d4868fee244a638d6ee6f5aab (diff) |
ACPI / PM: Do not disable wakeup GPEs that have not been enabled
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>
-rw-r--r-- | drivers/acpi/device_pm.c | 12 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 1 |
2 files changed, 11 insertions, 2 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 076af8149566..e6ff33ecd784 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -680,13 +680,21 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, | |||
680 | if (error) | 680 | if (error) |
681 | return error; | 681 | return error; |
682 | 682 | ||
683 | if (adev->wakeup.flags.enabled) | ||
684 | return 0; | ||
685 | |||
683 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 686 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); |
684 | if (ACPI_FAILURE(res)) { | 687 | if (ACPI_SUCCESS(res)) { |
688 | adev->wakeup.flags.enabled = 1; | ||
689 | } else { | ||
685 | acpi_disable_wakeup_device_power(adev); | 690 | acpi_disable_wakeup_device_power(adev); |
686 | return -EIO; | 691 | return -EIO; |
687 | } | 692 | } |
688 | } else { | 693 | } else { |
689 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 694 | if (adev->wakeup.flags.enabled) { |
695 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | ||
696 | adev->wakeup.flags.enabled = 0; | ||
697 | } | ||
690 | acpi_disable_wakeup_device_power(adev); | 698 | acpi_disable_wakeup_device_power(adev); |
691 | } | 699 | } |
692 | return 0; | 700 | return 0; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f34a0835aa4f..8de31d472fad 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -312,6 +312,7 @@ struct acpi_device_wakeup_flags { | |||
312 | u8 valid:1; /* Can successfully enable wakeup? */ | 312 | u8 valid:1; /* Can successfully enable wakeup? */ |
313 | u8 run_wake:1; /* Run-Wake GPE devices */ | 313 | u8 run_wake:1; /* Run-Wake GPE devices */ |
314 | u8 notifier_present:1; /* Wake-up notify handler has been installed */ | 314 | u8 notifier_present:1; /* Wake-up notify handler has been installed */ |
315 | u8 enabled:1; /* Enabled for wakeup */ | ||
315 | }; | 316 | }; |
316 | 317 | ||
317 | struct acpi_device_wakeup_context { | 318 | struct acpi_device_wakeup_context { |