[kernel/f15/master: 5/5] linux-2.6-acpi-fix-implicit-notify.patch: Fix implicit notify when there's more than one device per

Matthew Garrett mjg59 at fedoraproject.org
Thu Feb 24 15:59:14 UTC 2011


commit 31a889617a91f24ffbbf4a166b592890f7eb76cb
Author: Matthew Garrett <mjg at redhat.com>
Date:   Thu Feb 24 10:58:57 2011 -0500

    linux-2.6-acpi-fix-implicit-notify.patch: Fix implicit notify when there's
    more than one device per GPE

 kernel.spec                              |    8 ++-
 linux-2.6-acpi-fix-implicit-notify.patch |  129 ++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index d5c04d6..187843e 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -51,7 +51,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be prepended with "0.", so
 # for example a 3 here will become 0.3
 #
-%global baserelease 1
+%global baserelease 2
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -640,6 +640,7 @@ Patch390: linux-2.6-defaults-acpi-video.patch
 Patch391: linux-2.6-acpi-video-dos.patch
 Patch393: acpi-ec-add-delay-before-write.patch
 Patch394: linux-2.6-acpi-debug-infinite-loop.patch
+Patch395: linux-2.6-acpi-fix-implicit-notify.patch
 
 Patch450: linux-2.6-input-kill-stupid-messages.patch
 Patch452: linux-2.6.30-no-pcspkr-modalias.patch
@@ -1209,6 +1210,7 @@ ApplyPatch linux-2.6-defaults-acpi-video.patch
 ApplyPatch linux-2.6-acpi-video-dos.patch
 ApplyPatch acpi-ec-add-delay-before-write.patch
 ApplyPatch linux-2.6-acpi-debug-infinite-loop.patch
+ApplyPatch linux-2.6-acpi-fix-implicit-notify.patch
 
 # Various low-impact patches to aid debugging.
 ApplyPatch linux-2.6-debug-sizeof-structs.patch
@@ -1951,6 +1953,10 @@ fi
 # and build.
 
 %changelog
+* Thu Feb 24 2011 Matthew Garrett <mjg at redhat.com> 2.6.38-0.rc6.git2.2
+- linux-2.6-acpi-fix-implicit-notify.patch: Fix implicit notify when there's
+  more than one device per GPE
+
 * Wed Feb 23 2011 Chuck Ebbert <cebbert at redhat.com> 2.6.38-0.rc6.git2.1
 - Linux 2.6.38-rc6-git2
 
diff --git a/linux-2.6-acpi-fix-implicit-notify.patch b/linux-2.6-acpi-fix-implicit-notify.patch
new file mode 100644
index 0000000..7987be8
--- /dev/null
+++ b/linux-2.6-acpi-fix-implicit-notify.patch
@@ -0,0 +1,129 @@
+Index: linux-2.6/drivers/acpi/acpica/aclocal.h
+===================================================================
+--- linux-2.6.orig/drivers/acpi/acpica/aclocal.h
++++ linux-2.6/drivers/acpi/acpica/aclocal.h
+@@ -416,10 +416,15 @@ struct acpi_gpe_handler_info {
+ 	u8 originally_enabled;  /* True if GPE was originally enabled */
+ };
+ 
++struct acpi_gpe_notify_object {
++	struct acpi_namespace_node *node;
++	struct acpi_gpe_notify_object *next;
++};
++
+ union acpi_gpe_dispatch_info {
+ 	struct acpi_namespace_node *method_node;	/* Method node for this GPE level */
+ 	struct acpi_gpe_handler_info *handler;  /* Installed GPE handler */
+-	struct acpi_namespace_node *device_node;        /* Parent _PRW device for implicit notify */
++	struct acpi_gpe_notify_object device;   /* List of _PRW devices for implicit notify */
+ };
+ 
+ /*
+Index: linux-2.6/drivers/acpi/acpica/evxfgpe.c
+===================================================================
+--- linux-2.6.orig/drivers/acpi/acpica/evxfgpe.c
++++ linux-2.6/drivers/acpi/acpica/evxfgpe.c
+@@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake
+ 	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
+ 		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;
+ 
+Index: linux-2.6/drivers/acpi/acpica/evgpe.c
+===================================================================
+--- linux-2.6.orig/drivers/acpi/acpica/evgpe.c
++++ linux-2.6/drivers/acpi/acpica/evgpe.c
+@@ -457,6 +457,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
+ 	acpi_status status;
+ 	struct acpi_gpe_event_info *local_gpe_event_info;
+ 	struct acpi_evaluate_info *info;
++	struct acpi_gpe_notify_object *notify_object;
+ 
+ 	ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
+ 
+@@ -508,10 +509,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
+ 		 * from this thread -- because handlers may in turn run other
+ 		 * control methods.
+ 		 */
+-		status =
+-		    acpi_ev_queue_notify_request(local_gpe_event_info->dispatch.
+-						 device_node,
+-						 ACPI_NOTIFY_DEVICE_WAKE);
++		status = acpi_ev_queue_notify_request(
++				local_gpe_event_info->dispatch.device.node,
++				ACPI_NOTIFY_DEVICE_WAKE);
++
++		notify_object = local_gpe_event_info->dispatch.device.next;
++		while (ACPI_SUCCESS(status) && notify_object) {
++			status = acpi_ev_queue_notify_request(
++					notify_object->node,
++					ACPI_NOTIFY_DEVICE_WAKE);
++			notify_object = notify_object->next;
++		}
++
+ 		break;
+ 
+ 	case ACPI_GPE_DISPATCH_METHOD:


More information about the scm-commits mailing list