summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfgpe.c
diff options
context:
space:
mode:
authorJoel Becker <jlbec@evilplan.org>2011-03-28 09:44:26 -0700
committerJoel Becker <jlbec@evilplan.org>2011-03-28 09:44:26 -0700
commit99bdc3880c611c7f2061fbd5372ef81b40217e26 (patch)
treeef68a53e28e9ee53ce9db3642bab5fa5b3d44866 /drivers/acpi/acpica/evxfgpe.c
parented59992e8d91b70053c53d846a76f7e1ac000454 (diff)
parentb4e1b7e88b2c87c358c2a88bec0c76d25accc604 (diff)
Merge branch 'mlog_replace_for_39' of git://repo.or.cz/taoma-kernel into ocfs2-merge-window-fix
Diffstat (limited to 'drivers/acpi/acpica/evxfgpe.c')
-rw-r--r--drivers/acpi/acpica/evxfgpe.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 3b20a3401b6..52aaff3df56 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_namespace_node *device_node;
+ struct acpi_gpe_notify_object *notify_object;
acpi_cpu_flags flags;
+ u8 gpe_dispatch_mask;
ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
@@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
goto unlock_and_exit;
}
+ if (wake_device == ACPI_ROOT_OBJECT) {
+ goto out;
+ }
+
/*
* If there is no method or handler for this GPE, then the
* wake_device will be notified whenever this GPE fires (aka
* "implicit notify") Note: The GPE is assumed to be
* level-triggered (for windows compatibility).
*/
- if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) {
+ gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK;
+ if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE
+ && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) {
+ goto out;
+ }
- /* Validate wake_device is of type Device */
+ /* Validate wake_device is of type Device */
- device_node = ACPI_CAST_PTR(struct acpi_namespace_node,
- wake_device);
- if (device_node->type != ACPI_TYPE_DEVICE) {
- goto unlock_and_exit;
- }
+ device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
+ if (device_node->type != ACPI_TYPE_DEVICE) {
+ goto unlock_and_exit;
+ }
+
+ if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {
gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
ACPI_GPE_LEVEL_TRIGGERED);
- gpe_event_info->dispatch.device_node = device_node;
+ gpe_event_info->dispatch.device.node = device_node;
+ gpe_event_info->dispatch.device.next = NULL;
+ } else {
+ /* There are multiple devices to notify implicitly. */
+
+ notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object));
+ if (!notify_object) {
+ status = AE_NO_MEMORY;
+ goto unlock_and_exit;
+ }
+
+ notify_object->node = device_node;
+ notify_object->next = gpe_event_info->dispatch.device.next;
+ gpe_event_info->dispatch.device.next = notify_object;
}
+ out:
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
status = AE_OK;