diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-02-17 17:41:49 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-22 19:20:51 -0500 |
commit | f517709d65beed95f52f021b43e3035b52ef791a (patch) | |
tree | dd814cb7dc6b211fc6c31cadab1b77c12c137775 | |
parent | 9630bdd9b15d2f489c646d8bc04b60e53eb5ec78 (diff) |
ACPI / PM: Add more run-time wake-up fields
Use the run_wake flag to mark all devices for which run-time wake-up
events may be generated by the platform. Introduce a new wake-up
flag, always_enabled, for marking devices that should be permanently
enabled to generate run-time events. Also, introduce a reference
counter for run-wake devices and a function that will initialize all
of the run-time wake-up fields for given device.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Len Brown <len.brown@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/acpi/button.c | 2 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 37 | ||||
-rw-r--r-- | drivers/acpi/wakeup.c | 3 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 2 |
4 files changed, 33 insertions, 11 deletions
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 09ca3ce7a051..f53fbe307c9d 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -425,6 +425,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
425 | acpi_enable_gpe(device->wakeup.gpe_device, | 425 | acpi_enable_gpe(device->wakeup.gpe_device, |
426 | device->wakeup.gpe_number, | 426 | device->wakeup.gpe_number, |
427 | ACPI_GPE_TYPE_WAKE_RUN); | 427 | ACPI_GPE_TYPE_WAKE_RUN); |
428 | device->wakeup.run_wake_count++; | ||
428 | device->wakeup.state.enabled = 1; | 429 | device->wakeup.state.enabled = 1; |
429 | } | 430 | } |
430 | 431 | ||
@@ -448,6 +449,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
448 | acpi_disable_gpe(device->wakeup.gpe_device, | 449 | acpi_disable_gpe(device->wakeup.gpe_device, |
449 | device->wakeup.gpe_number, | 450 | device->wakeup.gpe_number, |
450 | ACPI_GPE_TYPE_WAKE_RUN); | 451 | ACPI_GPE_TYPE_WAKE_RUN); |
452 | device->wakeup.run_wake_count--; | ||
451 | device->wakeup.state.enabled = 0; | 453 | device->wakeup.state.enabled = 0; |
452 | } | 454 | } |
453 | 455 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3e009674f333..7491a52ad97a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -741,19 +741,39 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | |||
741 | return AE_OK; | 741 | return AE_OK; |
742 | } | 742 | } |
743 | 743 | ||
744 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 744 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) |
745 | { | 745 | { |
746 | acpi_status status = 0; | ||
747 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
748 | union acpi_object *package = NULL; | ||
749 | int psw_error; | ||
750 | |||
751 | struct acpi_device_id button_device_ids[] = { | 746 | struct acpi_device_id button_device_ids[] = { |
752 | {"PNP0C0D", 0}, | 747 | {"PNP0C0D", 0}, |
753 | {"PNP0C0C", 0}, | 748 | {"PNP0C0C", 0}, |
754 | {"PNP0C0E", 0}, | 749 | {"PNP0C0E", 0}, |
755 | {"", 0}, | 750 | {"", 0}, |
756 | }; | 751 | }; |
752 | acpi_status status; | ||
753 | acpi_event_status event_status; | ||
754 | |||
755 | device->wakeup.run_wake_count = 0; | ||
756 | |||
757 | /* Power button, Lid switch always enable wakeup */ | ||
758 | if (!acpi_match_device_ids(device, button_device_ids)) { | ||
759 | device->wakeup.flags.run_wake = 1; | ||
760 | device->wakeup.flags.always_enabled = 1; | ||
761 | return; | ||
762 | } | ||
763 | |||
764 | status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, | ||
765 | ACPI_NOT_ISR, &event_status); | ||
766 | if (status == AE_OK) | ||
767 | device->wakeup.flags.run_wake = | ||
768 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); | ||
769 | } | ||
770 | |||
771 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | ||
772 | { | ||
773 | acpi_status status = 0; | ||
774 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
775 | union acpi_object *package = NULL; | ||
776 | int psw_error; | ||
757 | 777 | ||
758 | /* _PRW */ | 778 | /* _PRW */ |
759 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 779 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); |
@@ -773,6 +793,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
773 | 793 | ||
774 | device->wakeup.flags.valid = 1; | 794 | device->wakeup.flags.valid = 1; |
775 | device->wakeup.prepare_count = 0; | 795 | device->wakeup.prepare_count = 0; |
796 | acpi_bus_set_run_wake_flags(device); | ||
776 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 797 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping |
777 | * system for the ACPI device with the _PRW object. | 798 | * system for the ACPI device with the _PRW object. |
778 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 799 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
@@ -784,10 +805,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
784 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 805 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
785 | "error in _DSW or _PSW evaluation\n")); | 806 | "error in _DSW or _PSW evaluation\n")); |
786 | 807 | ||
787 | /* Power button, Lid switch always enable wakeup */ | ||
788 | if (!acpi_match_device_ids(device, button_device_ids)) | ||
789 | device->wakeup.flags.run_wake = 1; | ||
790 | |||
791 | end: | 808 | end: |
792 | if (ACPI_FAILURE(status)) | 809 | if (ACPI_FAILURE(status)) |
793 | device->flags.wake_capable = 0; | 810 | device->flags.wake_capable = 0; |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 6783986c7469..4b9d339a6e28 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -110,7 +110,8 @@ int __init acpi_wakeup_device_init(void) | |||
110 | struct acpi_device, | 110 | struct acpi_device, |
111 | wakeup_list); | 111 | wakeup_list); |
112 | /* In case user doesn't load button driver */ | 112 | /* In case user doesn't load button driver */ |
113 | if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) | 113 | if (!dev->wakeup.flags.always_enabled || |
114 | dev->wakeup.state.enabled) | ||
114 | continue; | 115 | continue; |
115 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 116 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
116 | ACPI_GPE_TYPE_WAKE); | 117 | ACPI_GPE_TYPE_WAKE); |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3cd9ccdcbd8f..60fcff419352 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -242,6 +242,7 @@ struct acpi_device_perf { | |||
242 | struct acpi_device_wakeup_flags { | 242 | struct acpi_device_wakeup_flags { |
243 | u8 valid:1; /* Can successfully enable wakeup? */ | 243 | u8 valid:1; /* Can successfully enable wakeup? */ |
244 | u8 run_wake:1; /* Run-Wake GPE devices */ | 244 | u8 run_wake:1; /* Run-Wake GPE devices */ |
245 | u8 always_enabled:1; /* Run-wake devices that are always enabled */ | ||
245 | }; | 246 | }; |
246 | 247 | ||
247 | struct acpi_device_wakeup_state { | 248 | struct acpi_device_wakeup_state { |
@@ -256,6 +257,7 @@ struct acpi_device_wakeup { | |||
256 | struct acpi_device_wakeup_state state; | 257 | struct acpi_device_wakeup_state state; |
257 | struct acpi_device_wakeup_flags flags; | 258 | struct acpi_device_wakeup_flags flags; |
258 | int prepare_count; | 259 | int prepare_count; |
260 | int run_wake_count; | ||
259 | }; | 261 | }; |
260 | 262 | ||
261 | /* Device */ | 263 | /* Device */ |