diff mbox

Make current GPE changes to be consistent with ACPICA code base

Message ID 1270537259.3384.50.camel@minggr.sh.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lin Ming April 6, 2010, 7 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index 3e6ba99..5e094a2 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -85,6 +85,10 @@  acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
 						       u32 gpe_number);
 
+struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
+						     struct acpi_gpe_block_info
+						     *gpe_block);
+
 /*
  * evgpeblk
  */
@@ -118,9 +122,6 @@  acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
 
 u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
 
-acpi_status
-acpi_ev_check_for_wake_only_gpe(struct acpi_gpe_event_info *gpe_event_info);
-
 acpi_status acpi_ev_gpe_initialize(void);
 
 /*
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 24b8faa..5a6203a 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -427,8 +427,8 @@  struct acpi_gpe_event_info {
 	struct acpi_gpe_register_info *register_info;	/* Backpointer to register info */
 	u8 flags;		/* Misc info about this GPE */
 	u8 gpe_number;		/* This GPE */
-	u8 runtime_count;
-	u8 wakeup_count;
+	u8 runtime_count;	/* References to a run GPE */
+	u8 wakeup_count;	/* References to a wake GPE */
 };
 
 /* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -454,6 +454,7 @@  struct acpi_gpe_block_info {
 	struct acpi_gpe_event_info *event_info;	/* One for each GPE */
 	struct acpi_generic_address block_address;	/* Base address of the block */
 	u32 register_count;	/* Number of register pairs in block */
+	u16 gpe_count;		/* Number of individual GPEs in block */
 	u8 block_base_number;	/* Base GPE number for this block */
 };
 
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index b9d50ef..deb26f4 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -60,7 +60,8 @@  static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ * DESCRIPTION: Updates GPE register enable masks based upon whether there are
+ *              references (either wake or run) to this GPE
  *
  ******************************************************************************/
 
@@ -81,14 +82,20 @@  acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
 	    (1 <<
 	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
 
+	/* Clear the wake/run bits up front */
+
 	ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit);
 	ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
 
-	if (gpe_event_info->runtime_count)
+	/* Set the mask bits only if there are references to this GPE */
+
+	if (gpe_event_info->runtime_count) {
 		ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit);
+	}
 
-	if (gpe_event_info->wakeup_count)
+	if (gpe_event_info->wakeup_count) {
 		ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit);
+	}
 
 	return_ACPI_STATUS(AE_OK);
 }
@@ -101,7 +108,10 @@  acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
+ *              of type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
  *
  ******************************************************************************/
 
@@ -109,20 +119,36 @@  acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 {
 	acpi_status status;
 
+
 	ACPI_FUNCTION_TRACE(ev_enable_gpe);
 
-	/* Make sure HW enable masks are updated */
+
+	/*
+	 * We will only allow a GPE to be enabled if it has either an
+	 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
+	 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
+	 * first time it fires.
+	 */
+	if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
+		return_ACPI_STATUS(AE_NO_HANDLER);
+	}
+
+	/* Ensure the HW enable masks are current */
 
 	status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
+	}
+
+	/* Clear the GPE (of stale events) */
 
-	/* Clear the GPE (of stale events), then enable it */
 	status = acpi_hw_clear_gpe(gpe_event_info);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
+	}
 
 	/* Enable the requested GPE */
+
 	status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
 	return_ACPI_STATUS(status);
 }
@@ -135,7 +161,10 @@  acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable a GPE based on the GPE type
+ * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
+ *              regardless of the type or number of references.
+ *
+ * Note: The GPE lock should be already acquired when this function is called.
  *
  ******************************************************************************/
 
@@ -145,24 +174,71 @@  acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 
 	ACPI_FUNCTION_TRACE(ev_disable_gpe);
 
-	/* Make sure HW enable masks are updated */
+
+	/*
+	 * Note: Always disable the GPE, even if we think that that it is already
+	 * disabled. It is possible that the AML or some other code has enabled
+	 * the GPE behind our back.
+	 */
+
+	/* Ensure the HW enable masks are current */
 
 	status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
+	}
 
 	/*
-	 * Even if we don't know the GPE type, make sure that we always
-	 * disable it. low_disable_gpe will just clear the enable bit for this
-	 * GPE and write it. It will not write out the current GPE enable mask,
-	 * since this may inadvertently enable GPEs too early, if a rogue GPE has
-	 * come in during ACPICA initialization - possibly as a result of AML or
-	 * other code that has enabled the GPE.
+	 * Always H/W disable this GPE, even if we don't know the GPE type.
+	 * Simply clear the enable bit for this particular GPE, but do not
+	 * write out the current GPE enable mask since this may inadvertently
+	 * enable GPEs too early. An example is a rogue GPE that has arrived
+	 * during ACPICA initialization - possibly because AML or other code
+	 * has enabled the GPE.
 	 */
 	status = acpi_hw_low_disable_gpe(gpe_event_info);
 	return_ACPI_STATUS(status);
 }
 
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_low_get_gpe_info
+ *
+ * PARAMETERS:  gpe_number          - Raw GPE number
+ *              gpe_block           - A GPE info block
+ *
+ * RETURN:      A GPE event_info struct. NULL if not a valid GPE (The gpe_number
+ *              is not within the specified GPE block)
+ *
+ * DESCRIPTION: Returns the event_info struct associated with this GPE. This is
+ *              the low-level implementation of ev_get_gpe_event_info.
+ *
+ ******************************************************************************/
+
+struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
+						     struct acpi_gpe_block_info
+						     *gpe_block)
+{
+	u32 gpe_index;
+
+	/*
+	 * Validate that the gpe_number is within the specified gpe_block.
+	 * (Two steps)
+	 */
+	if (!gpe_block || (gpe_number < gpe_block->block_base_number)) {
+		return (NULL);
+	}
+
+	gpe_index = gpe_number - gpe_block->block_base_number;
+	if (gpe_index >= gpe_block->gpe_count) {
+		return (NULL);
+	}
+
+	return (&gpe_block->event_info[gpe_index]);
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_get_gpe_event_info
@@ -184,7 +260,7 @@  struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
 						       u32 gpe_number)
 {
 	union acpi_operand_object *obj_desc;
-	struct acpi_gpe_block_info *gpe_block;
+	struct acpi_gpe_event_info *gpe_info;
 	u32 i;
 
 	ACPI_FUNCTION_ENTRY();
@@ -196,17 +272,11 @@  struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
 		/* Examine GPE Block 0 and 1 (These blocks are permanent) */
 
 		for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
-			gpe_block = acpi_gbl_gpe_fadt_blocks[i];
-			if (gpe_block) {
-				if ((gpe_number >= gpe_block->block_base_number)
-				    && (gpe_number <
-					gpe_block->block_base_number +
-					(gpe_block->register_count * 8))) {
-					return (&gpe_block->
-						event_info[gpe_number -
-							   gpe_block->
-							   block_base_number]);
-				}
+			gpe_info = acpi_ev_low_get_gpe_info(gpe_number,
+							    acpi_gbl_gpe_fadt_blocks
+							    [i]);
+			if (gpe_info) {
+				return (gpe_info);
 			}
 		}
 
@@ -223,16 +293,8 @@  struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
 		return (NULL);
 	}
 
-	gpe_block = obj_desc->device.gpe_block;
-
-	if ((gpe_number >= gpe_block->block_base_number) &&
-	    (gpe_number <
-	     gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-		return (&gpe_block->
-			event_info[gpe_number - gpe_block->block_base_number]);
-	}
-
-	return (NULL);
+	return (acpi_ev_low_get_gpe_info
+		(gpe_number, obj_desc->device.gpe_block));
 }
 
 /*******************************************************************************
@@ -389,7 +451,7 @@  static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
 		return_VOID;
 	}
 
-	/* Set the GPE flags for return to enabled state */
+	/* Update the GPE register masks for return to enabled state */
 
 	(void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
 
@@ -569,15 +631,18 @@  acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
 
 	default:
 
-		/* No handler or method to run! */
-
+		/*
+		 * No handler or method to run!
+		 * 03/2010: This case should no longer be possible. We will not allow
+		 * a GPE to be enabled if it has no handler or method.
+		 */
 		ACPI_ERROR((AE_INFO,
 			    "No handler or method for GPE[0x%2X], disabling event",
 			    gpe_number));
 
 		/*
-		 * Disable the GPE. The GPE will remain disabled until the ACPICA
-		 * Core Subsystem is restarted, or a handler is installed.
+		 * Disable the GPE. The GPE will remain disabled a handler
+		 * is installed or ACPICA is restarted.
 		 */
 		status = acpi_ev_disable_gpe(gpe_event_info);
 		if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index fa47e35..85ded1f 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -51,7 +51,7 @@  ACPI_MODULE_NAME("evgpeblk")
 
 /* Local prototypes */
 static acpi_status
-acpi_ev_save_method_info(acpi_handle obj_handle,
+acpi_ev_match_gpe_method(acpi_handle obj_handle,
 			 u32 level, void *obj_desc, void **return_value);
 
 static acpi_status
@@ -104,9 +104,7 @@  u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
 
 		while (gpe_block) {
 			if ((&gpe_block->event_info[0] <= gpe_event_info) &&
-			    (&gpe_block->event_info[((acpi_size)
-						     gpe_block->
-						     register_count) * 8] >
+			    (&gpe_block->event_info[gpe_block->gpe_count] >
 			     gpe_event_info)) {
 				return (TRUE);
 			}
@@ -229,7 +227,7 @@  acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_save_method_info
+ * FUNCTION:    acpi_ev_match_gpe_method
  *
  * PARAMETERS:  Callback from walk_namespace
  *
@@ -241,8 +239,7 @@  acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  *              information for quick lookup during GPE dispatch
  *
  *              The name of each GPE control method is of the form:
- *              "_Lxx" or "_Exx"
- *              Where:
+ *              "_Lxx" or "_Exx", where:
  *                  L      - means that the GPE is level triggered
  *                  E      - means that the GPE is edge triggered
  *                  xx     - is the GPE number [in HEX]
@@ -250,9 +247,11 @@  acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  ******************************************************************************/
 
 static acpi_status
-acpi_ev_save_method_info(acpi_handle obj_handle,
+acpi_ev_match_gpe_method(acpi_handle obj_handle,
 			 u32 level, void *obj_desc, void **return_value)
 {
+	struct acpi_namespace_node *method_node =
+	    ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
 	struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
 	struct acpi_gpe_event_info *gpe_event_info;
 	u32 gpe_number;
@@ -262,21 +261,25 @@  acpi_ev_save_method_info(acpi_handle obj_handle,
 	ACPI_FUNCTION_TRACE(ev_save_method_info);
 
 	/*
-	 * _Lxx and _Exx GPE method support
+	 * Match and decode the _Lxx and _Exx GPE method names
 	 *
-	 * 1) Extract the name from the object and convert to a string
+	 * 1) Extract the method name and null terminate it
 	 */
-	ACPI_MOVE_32_TO_32(name,
-			   &((struct acpi_namespace_node *)obj_handle)->name.
-			   integer);
+	ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
 	name[ACPI_NAME_SIZE] = 0;
 
+	/* 2) Name must begin with an underscore */
+
+	if (name[0] != '_') {
+		return_ACPI_STATUS(AE_OK);	/* Ignore this method */
+	}
+
 	/*
-	 * 2) Edge/Level determination is based on the 2nd character
+	 * 3) Edge/Level determination is based on the 2nd character
 	 *    of the method name
 	 *
-	 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
-	 * if a _PRW object is found that points to this GPE.
+	 * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
+	 * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
 	 */
 	switch (name[1]) {
 	case 'L':
@@ -288,7 +291,7 @@  acpi_ev_save_method_info(acpi_handle obj_handle,
 		break;
 
 	default:
-		/* Unknown method type, just ignore it! */
+		/* Unknown method type, just ignore it */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 				  "Ignoring unknown GPE method type: %s "
@@ -296,7 +299,7 @@  acpi_ev_save_method_info(acpi_handle obj_handle,
 		return_ACPI_STATUS(AE_OK);
 	}
 
-	/* Convert the last two characters of the name to the GPE Number */
+	/* 4) The last two characters of the name are the hex GPE Number */
 
 	gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
 	if (gpe_number == ACPI_UINT32_MAX) {
@@ -311,28 +314,22 @@  acpi_ev_save_method_info(acpi_handle obj_handle,
 
 	/* Ensure that we have a valid GPE number for this GPE block */
 
-	if ((gpe_number < gpe_block->block_base_number) ||
-	    (gpe_number >= (gpe_block->block_base_number +
-			    (gpe_block->register_count * 8)))) {
+	gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
+	if (!gpe_event_info) {
 		/*
-		 * Not valid for this GPE block, just ignore it. However, it may be
-		 * valid for a different GPE block, since GPE0 and GPE1 methods both
-		 * appear under \_GPE.
+		 * This gpe_number is not valid for this GPE block, just ignore it.
+		 * However, it may be valid for a different GPE block, since GPE0
+		 * and GPE1 methods both appear under \_GPE.
 		 */
 		return_ACPI_STATUS(AE_OK);
 	}
 
 	/*
-	 * Now we can add this information to the gpe_event_info block for use
-	 * during dispatch of this GPE.
+	 * Add the GPE information from above to the gpe_event_info block for
+	 * use during dispatch of this GPE.
 	 */
-	gpe_event_info =
-	    &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
-
-	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD);
-
-	gpe_event_info->dispatch.method_node =
-	    (struct acpi_namespace_node *)obj_handle;
+	gpe_event_info->flags = (u8)(type | ACPI_GPE_DISPATCH_METHOD);
+	gpe_event_info->dispatch.method_node = method_node;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 			  "Registered GPE method %s as GPE number 0x%.2X\n",
@@ -351,7 +348,7 @@  acpi_ev_save_method_info(acpi_handle obj_handle,
  *
  * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
  *              Device. Run the _PRW method. If present, extract the GPE
- *              number and mark the GPE as a WAKE GPE.
+ *              number and mark the GPE as a CAN_WAKE GPE.
  *
  ******************************************************************************/
 
@@ -377,7 +374,7 @@  acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
 					 ACPI_BTYPE_PACKAGE, &pkg_desc);
 	if (ACPI_FAILURE(status)) {
 
-		/* Ignore all errors from _PRW, we don't want to abort the subsystem */
+		/* Ignore all errors from _PRW, we don't want to abort the walk */
 
 		return_ACPI_STATUS(AE_OK);
 	}
@@ -439,13 +436,13 @@  acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
 	 *     2) The GPE index(number) is within the range of the Gpe Block
 	 *          associated with the GPE device.
 	 */
-	if ((gpe_device == target_gpe_device) &&
-	    (gpe_number >= gpe_block->block_base_number) &&
-	    (gpe_number < gpe_block->block_base_number +
-	     (gpe_block->register_count * 8))) {
-		gpe_event_info = &gpe_block->event_info[gpe_number -
-							gpe_block->
-							block_base_number];
+	if (gpe_device != target_gpe_device) {
+		goto cleanup;
+	}
+
+	gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
+	if (gpe_event_info) {
+		/* This GPE can wake the system */
 
 		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
 	}
@@ -705,8 +702,7 @@  acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
 		acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	}
 
-	acpi_current_gpe_count -=
-	    gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;
+	acpi_current_gpe_count -= gpe_block->gpe_count;
 
 	/* Free the gpe_block */
 
@@ -760,9 +756,7 @@  acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
 	 * Allocate the GPE event_info block. There are eight distinct GPEs
 	 * per register. Initialization to zeros is sufficient.
 	 */
-	gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block->
-					       register_count *
-					       ACPI_GPE_REGISTER_WIDTH) *
+	gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->gpe_count *
 					      sizeof(struct
 						     acpi_gpe_event_info));
 	if (!gpe_event_info) {
@@ -897,6 +891,7 @@  acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 	/* Initialize the new GPE block */
 
 	gpe_block->node = gpe_device;
+	gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
 	gpe_block->register_count = register_count;
 	gpe_block->block_base_number = gpe_block_base_number;
 
@@ -925,7 +920,7 @@  acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 
 	status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
 					ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
-					acpi_ev_save_method_info, NULL,
+					acpi_ev_match_gpe_method, NULL,
 					gpe_block, NULL);
 
 	/* Return the new block */
@@ -938,14 +933,13 @@  acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 			  "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
 			  (u32) gpe_block->block_base_number,
 			  (u32) (gpe_block->block_base_number +
-				 ((gpe_block->register_count *
-				   ACPI_GPE_REGISTER_WIDTH) - 1)),
+				(gpe_block->gpe_count - 1)),
 			  gpe_device->name.ascii, gpe_block->register_count,
 			  interrupt_number));
 
 	/* Update global count of currently available GPEs */
 
-	acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH;
+	acpi_current_gpe_count += gpe_block->gpe_count;
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -969,10 +963,13 @@  acpi_status
 acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
 			     struct acpi_gpe_block_info *gpe_block)
 {
+	acpi_status status;
 	struct acpi_gpe_event_info *gpe_event_info;
 	struct acpi_gpe_walk_info gpe_info;
 	u32 wake_gpe_count;
 	u32 gpe_enabled_count;
+	u32 gpe_index;
+	u32 gpe_number;
 	u32 i;
 	u32 j;
 
@@ -998,50 +995,62 @@  acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
 		gpe_info.gpe_block = gpe_block;
 		gpe_info.gpe_device = gpe_device;
 
-		acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+		status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 					   ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
 					   acpi_ev_match_prw_and_gpe, NULL,
 					   &gpe_info, NULL);
+		if (ACPI_FAILURE(status)) {
+			ACPI_EXCEPTION((AE_INFO, status,
+					"While executing _PRW methods"));
+		}
 	}
 
 	/*
-	 * Enable all GPEs that have a corresponding method and aren't
+	 * Enable all GPEs that have a corresponding method and are not
 	 * capable of generating wakeups. Any other GPEs within this block
-	 * must be enabled via the acpi_enable_gpe() interface.
+	 * must be enabled via the acpi_enable_gpe interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
-	if (gpe_device == acpi_gbl_fadt_gpe_device)
+
+	if (gpe_device == acpi_gbl_fadt_gpe_device) {
 		gpe_device = NULL;
+	}
 
 	for (i = 0; i < gpe_block->register_count; i++) {
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-			acpi_status status;
-			acpi_size gpe_index;
-			int gpe_number;
 
 			/* Get the info block for this particular GPE */
-			gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j;
+
+			gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
 			gpe_event_info = &gpe_block->event_info[gpe_index];
 
 			if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
 				wake_gpe_count++;
-				if (acpi_gbl_leave_wake_gpes_disabled)
+				if (acpi_gbl_leave_wake_gpes_disabled) {
 					continue;
+				}
 			}
 
-			if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD))
+			/* Ignore GPEs that have no corresponding _Lxx/_Exx method */
+
+			if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
 				continue;
+			}
+
+			/* Enable this GPE */
 
 			gpe_number = gpe_index + gpe_block->block_base_number;
 			status = acpi_enable_gpe(gpe_device, gpe_number,
-						ACPI_GPE_TYPE_RUNTIME);
-			if (ACPI_FAILURE(status))
-				ACPI_ERROR((AE_INFO,
-						"Failed to enable GPE %02X\n",
+						 ACPI_GPE_TYPE_RUNTIME);
+			if (ACPI_FAILURE(status)) {
+				ACPI_EXCEPTION((AE_INFO, status,
+						"Could not enable GPE 0x%02X",
 						gpe_number));
-			else
-				gpe_enabled_count++;
+				continue;
+			}
+
+			gpe_enabled_count++;
 		}
 	}
 
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index ca04823..cc82502 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -682,14 +682,13 @@  acpi_install_gpe_handler(acpi_handle gpe_device,
 
 	/* Parameter validation */
 
-	if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
-		status = AE_BAD_PARAMETER;
-		goto exit;
+	if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 	if (ACPI_FAILURE(status)) {
-		goto exit;
+		return_ACPI_STATUS(status);
 	}
 
 	/* Ensure that we have a valid GPE number */
@@ -720,6 +719,13 @@  acpi_install_gpe_handler(acpi_handle gpe_device,
 	handler->context = context;
 	handler->method_node = gpe_event_info->dispatch.method_node;
 
+	/* Disable the GPE before installing the handler */
+
+	status = acpi_ev_disable_gpe(gpe_event_info);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
 	/* Install the handler */
 
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
@@ -733,12 +739,8 @@  acpi_install_gpe_handler(acpi_handle gpe_device,
 
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 
-      unlock_and_exit:
+unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-      exit:
-	if (ACPI_FAILURE(status))
-		ACPI_EXCEPTION((AE_INFO, status,
-				"Installing notify handler failed"));
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 5ff32c7..7c7bbb4 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -203,21 +203,26 @@  ACPI_EXPORT_SYMBOL(acpi_enable_event)
  *
  * FUNCTION:    acpi_set_gpe
  *
- * PARAMETERS:  gpe_device      - Parent GPE Device
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              action          - Enable or disable
- *                                Called from ISR or not
+ *              action          - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable or disable an ACPI event (general purpose)
+ * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
+ *              the reference count mechanism used in the acpi_enable_gpe and
+ *              acpi_disable_gpe interfaces -- and should be used with care.
+ *
+ * Note: Typically used to disable a runtime GPE for short period of time,
+ * then re-enable it, without disturbing the existing reference counts. This
+ * is useful, for example, in the Embedded Controller (EC) driver.
  *
  ******************************************************************************/
 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
 {
-	acpi_status status = AE_OK;
-	acpi_cpu_flags flags;
 	struct acpi_gpe_event_info *gpe_event_info;
+	acpi_status status;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE(acpi_set_gpe);
 
@@ -243,7 +248,6 @@  acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
 		break;
 
 	default:
-		ACPI_ERROR((AE_INFO, "Invalid action\n"));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -259,25 +263,31 @@  ACPI_EXPORT_SYMBOL(acpi_set_gpe)
  *
  * FUNCTION:    acpi_enable_gpe
  *
- * PARAMETERS:  gpe_device      - Parent GPE Device
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              type            - Purpose the GPE will be used for
+ *              gpe_type        - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
+ *                                or both
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Take a reference to a GPE and enable it if necessary
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ *              hardware-enabled (for runtime GPEs), or the GPE register mask
+ *              is updated (for wake GPEs).
  *
  ******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
 {
 	acpi_status status = AE_OK;
-	acpi_cpu_flags flags;
 	struct acpi_gpe_event_info *gpe_event_info;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
 
-	if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+	/* Parameter validation */
+
+	if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
 
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
@@ -289,26 +299,43 @@  acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
 		goto unlock_and_exit;
 	}
 
-	if (type & ACPI_GPE_TYPE_RUNTIME) {
-		if (++gpe_event_info->runtime_count == 1) {
+	if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
+		if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
+			status = AE_LIMIT;	/* Too many references */
+			goto unlock_and_exit;
+		}
+
+		gpe_event_info->runtime_count++;
+		if (gpe_event_info->runtime_count == 1) {
 			status = acpi_ev_enable_gpe(gpe_event_info);
-			if (ACPI_FAILURE(status))
+			if (ACPI_FAILURE(status)) {
 				gpe_event_info->runtime_count--;
+				goto unlock_and_exit;
+			}
 		}
 	}
 
-	if (type & ACPI_GPE_TYPE_WAKE) {
+	if (gpe_type & ACPI_GPE_TYPE_WAKE) {
+		/* The GPE must have the ability to wake the system */
+
 		if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
-			status = AE_BAD_PARAMETER;
+			status = AE_TYPE;
+			goto unlock_and_exit;
+		}
+
+		if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) {
+			status = AE_LIMIT;	/* Too many references */
 			goto unlock_and_exit;
 		}
 
 		/*
-		 * Wake-up GPEs are only enabled right prior to putting the
-		 * system into a sleep state.
+		 * Update the enable mask on the first wakeup reference. Wake GPEs
+		 * are only hardware-enabled just before sleeping.
 		 */
-		if (++gpe_event_info->wakeup_count == 1)
-			acpi_ev_update_gpe_enable_masks(gpe_event_info);
+		gpe_event_info->wakeup_count++;
+		if (gpe_event_info->wakeup_count == 1) {
+			(void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
+		}
 	}
 
 unlock_and_exit:
@@ -321,27 +348,34 @@  ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
  *
  * FUNCTION:    acpi_disable_gpe
  *
- * PARAMETERS:  gpe_device      - Parent GPE Device
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              type            - Purpose the GPE won't be used for any more
+ *              gpe_type        - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
+ *                                or both
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Release a reference to a GPE and disable it if necessary
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ *              removed, only then is the GPE disabled (for runtime GPEs), or
+ *              the GPE mask bit disabled (for wake GPEs)
  *
  ******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type)
 {
 	acpi_status status = AE_OK;
-	acpi_cpu_flags flags;
 	struct acpi_gpe_event_info *gpe_event_info;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
 
-	if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
+	/* Parameter validation */
+
+	if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
 
 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
 	/* Ensure that we have a valid GPE number */
 
 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@@ -350,18 +384,39 @@  acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
 		goto unlock_and_exit;
 	}
 
-	if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
-		if (--gpe_event_info->runtime_count == 0)
+	/* Hardware-disable a runtime GPE on removal of the last reference */
+
+	if (gpe_type & ACPI_GPE_TYPE_RUNTIME) {
+		if (!gpe_event_info->runtime_count) {
+			status = AE_LIMIT;	/* There are no references to remove */
+			goto unlock_and_exit;
+		}
+
+		gpe_event_info->runtime_count--;
+		if (!gpe_event_info->runtime_count) {
 			status = acpi_ev_disable_gpe(gpe_event_info);
+			if (ACPI_FAILURE(status)) {
+				gpe_event_info->runtime_count++;
+				goto unlock_and_exit;
+			}
+		}
 	}
 
-	if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) {
-		/*
-		 * Wake-up GPEs are not enabled after leaving system sleep
-		 * states, so we don't need to disable them here.
-		 */
-		if (--gpe_event_info->wakeup_count == 0)
-			acpi_ev_update_gpe_enable_masks(gpe_event_info);
+	/*
+	 * Update masks for wake GPE on removal of the last reference.
+	 * No need to hardware-disable wake GPEs here, they are not currently
+	 * enabled.
+	 */
+	if (gpe_type & ACPI_GPE_TYPE_WAKE) {
+		if (!gpe_event_info->wakeup_count) {
+			status = AE_LIMIT;	/* There are no references to remove */
+			goto unlock_and_exit;
+		}
+
+		gpe_event_info->wakeup_count--;
+		if (!gpe_event_info->wakeup_count) {
+			(void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
+		}
 	}
 
 unlock_and_exit:
@@ -465,30 +520,23 @@  ACPI_EXPORT_SYMBOL(acpi_clear_event)
  *
  * FUNCTION:    acpi_clear_gpe
  *
- * PARAMETERS:  gpe_device      - Parent GPE Device
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Called from an ISR or not
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Clear an ACPI event (general purpose)
  *
  ******************************************************************************/
-acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
 {
 	acpi_status status = AE_OK;
 	struct acpi_gpe_event_info *gpe_event_info;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE(acpi_clear_gpe);
 
-	/* Use semaphore lock if not executing at interrupt level */
-
-	if (flags & ACPI_NOT_ISR) {
-		status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
+	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 	/* Ensure that we have a valid GPE number */
 
@@ -501,9 +549,7 @@  acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
 	status = acpi_hw_clear_gpe(gpe_event_info);
 
       unlock_and_exit:
-	if (flags & ACPI_NOT_ISR) {
-		(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-	}
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS(status);
 }
 
@@ -569,9 +615,8 @@  ACPI_EXPORT_SYMBOL(acpi_get_event_status)
  *
  * FUNCTION:    acpi_get_gpe_status
  *
- * PARAMETERS:  gpe_device      - Parent GPE Device
+ * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Called from an ISR or not
  *              event_status    - Where the current status of the event will
  *                                be returned
  *
@@ -582,21 +627,15 @@  ACPI_EXPORT_SYMBOL(acpi_get_event_status)
  ******************************************************************************/
 acpi_status
 acpi_get_gpe_status(acpi_handle gpe_device,
-		    u32 gpe_number, u32 flags, acpi_event_status * event_status)
+		    u32 gpe_number, acpi_event_status *event_status)
 {
 	acpi_status status = AE_OK;
 	struct acpi_gpe_event_info *gpe_event_info;
+	acpi_cpu_flags flags;
 
 	ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
 
-	/* Use semaphore lock if not executing at interrupt level */
-
-	if (flags & ACPI_NOT_ISR) {
-		status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
+	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 
 	/* Ensure that we have a valid GPE number */
 
@@ -614,9 +653,7 @@  acpi_get_gpe_status(acpi_handle gpe_device,
 		*event_status |= ACPI_EVENT_FLAG_HANDLE;
 
       unlock_and_exit:
-	if (flags & ACPI_NOT_ISR) {
-		(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-	}
+	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS(status);
 }
 
@@ -673,20 +710,15 @@  acpi_install_gpe_block(acpi_handle gpe_device,
 		goto unlock_and_exit;
 	}
 
-	/* Run the _PRW methods and enable the GPEs */
-
-	status = acpi_ev_initialize_gpe_block(node, gpe_block);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
-	/* Get the device_object attached to the node */
+	/* Install block in the device_object attached to the node */
 
 	obj_desc = acpi_ns_get_attached_object(node);
 	if (!obj_desc) {
 
-		/* No object, create a new one */
-
+		/*
+		 * No object, create a new one (Device nodes do not always have
+		 * an attached object)
+		 */
 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
 		if (!obj_desc) {
 			status = AE_NO_MEMORY;
@@ -705,10 +737,14 @@  acpi_install_gpe_block(acpi_handle gpe_device,
 		}
 	}
 
-	/* Install the GPE block in the device_object */
+	/* Now install the GPE block in the device_object */
 
 	obj_desc->device.gpe_block = gpe_block;
 
+	/* Run the _PRW methods and enable the runtime GPEs in the new block */
+
+	status = acpi_ev_initialize_gpe_block(node, gpe_block);
+
       unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS(status);
@@ -839,8 +875,7 @@  acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 
 	/* Increment Index by the number of GPEs in this block */
 
-	info->next_block_base_index +=
-	    (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
+	info->next_block_base_index += gpe_block->gpe_count;
 
 	if (info->index < info->next_block_base_index) {
 		/*
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 3f3f48b..10e104c 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -119,33 +119,6 @@  acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state)
 			status = AE_AML_OPERAND_TYPE;
 			break;
 		}
-#ifdef ACPI_GPE_NOTIFY_CHECK
-		/*
-		 * GPE method wake/notify check.  Here, we want to ensure that we
-		 * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
-		 * GPE method during system runtime.  If we do, the GPE is marked
-		 * as "wake-only" and disabled.
-		 *
-		 * 1) Is the Notify() value == device_wake?
-		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
-		 * 3) Did the original GPE happen at system runtime?
-		 *    (versus during wake)
-		 *
-		 * If all three cases are true, this is a wake-only GPE that should
-		 * be disabled at runtime.
-		 */
-		if (value == 2) {	/* device_wake */
-			status =
-			    acpi_ev_check_for_wake_only_gpe(walk_state->
-							    gpe_event_info);
-			if (ACPI_FAILURE(status)) {
-
-				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */
-
-				return_ACPI_STATUS(AE_OK)
-			}
-		}
-#endif
 
 		/*
 		 * Dispatch the notify to the appropriate handler
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 95c90ff..9e5396a 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -764,7 +764,7 @@  static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
 	}
 
 	status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number,
-					ACPI_NOT_ISR, &event_status);
+					&event_status);
 	if (status == AE_OK)
 		device->wakeup.flags.run_wake =
 				!!(event_status & ACPI_EVENT_FLAG_HANDLE);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 743f244..b6093bc 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -302,8 +302,7 @@  static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
 				"Invalid GPE 0x%x\n", index));
 			goto end;
 		}
-		result = acpi_get_gpe_status(*handle, index,
-						ACPI_NOT_ISR, status);
+		result = acpi_get_gpe_status(*handle, index, status);
 	} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
 		result = acpi_get_event_status(index - num_gpes, status);
 
@@ -394,7 +393,7 @@  static ssize_t counter_set(struct kobject *kobj,
 			result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
 		else if (!strcmp(buf, "clear\n") &&
 				(status & ACPI_EVENT_FLAG_SET))
-			result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
+			result = acpi_clear_gpe(handle, index);
 		else
 			all_counters[index].count = strtoul(buf, NULL, 0);
 	} else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index 5b2e5e8..5958d78 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -87,7 +87,7 @@ 
 #define AE_NO_GLOBAL_LOCK               (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
 #define AE_ABORT_METHOD                 (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
 #define AE_SAME_HANDLER                 (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
-#define AE_WAKE_ONLY_GPE                (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_HANDLER                   (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
 #define AE_OWNER_ID_LIMIT               (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
 
 #define AE_CODE_ENV_MAX                 0x001B
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index f753222..c82c3b5 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -284,16 +284,17 @@  acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
  */
 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action);
 
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type);
+acpi_status
+acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type);
 
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type);
+acpi_status
+acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type);
 
-acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
+acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
 
 acpi_status
 acpi_get_gpe_status(acpi_handle gpe_device,
-		    u32 gpe_number,
-		    u32 flags, acpi_event_status * event_status);
+		    u32 gpe_number, acpi_event_status *event_status);
 
 acpi_status acpi_disable_all_gpes(void);
 
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3f08e64..de5e99a 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -663,44 +663,42 @@  typedef u32 acpi_event_status;
 #define ACPI_GPE_MAX                    0xFF
 #define ACPI_NUM_GPE                    256
 
+/* Actions for acpi_set_gpe */
+
 #define ACPI_GPE_ENABLE                 0
 #define ACPI_GPE_DISABLE                1
 
+/* gpe_types for acpi_enable_gpe and acpi_disable_gpe */
+
+#define ACPI_GPE_TYPE_WAKE              (u8) 0x01
+#define ACPI_GPE_TYPE_RUNTIME           (u8) 0x02
+#define ACPI_GPE_TYPE_WAKE_RUN          (u8) 0x03
+
 /*
  * GPE info flags - Per GPE
- * +-+-+-+---+-+-+-+
- * |7|6|5|4:3|2|1|0|
- * +-+-+-+---+-+-+-+
- *  | | |  |  | | |
- *  | | |  |  | | +--- Interrupt type: Edge or Level Triggered
- *  | | |  |  | +--- GPE can wake the system
- *  | | |  |  +--- Unused
- *  | | |  +--- Type of dispatch -- to method, handler, or none
- *  | | +--- Unused
- *  | +--- Unused
- *  +--- Unused
+ * +-------+---+-+-+
+ * |  7:4  |3:2|1|0|
+ * +-------+---+-+-+
+ *     |     |  | |
+ *     |     |  | +--- Interrupt type: edge or level triggered
+ *     |     |  +----- GPE can wake the system
+ *     |     +-------- Type of dispatch:to method, handler, or none
+ *     +-------------- <Reserved>
  */
 #define ACPI_GPE_XRUPT_TYPE_MASK        (u8) 0x01
 #define ACPI_GPE_LEVEL_TRIGGERED        (u8) 0x01
 #define ACPI_GPE_EDGE_TRIGGERED         (u8) 0x00
 
-#define ACPI_GPE_TYPE_MASK              (u8) 0x06
-#define ACPI_GPE_TYPE_WAKE_RUN          (u8) 0x06
-#define ACPI_GPE_TYPE_WAKE              (u8) 0x02
-#define ACPI_GPE_TYPE_RUNTIME           (u8) 0x04	/* Default */
 #define ACPI_GPE_CAN_WAKE		(u8) 0x02
 
-#define ACPI_GPE_DISPATCH_MASK          (u8) 0x18
-#define ACPI_GPE_DISPATCH_HANDLER       (u8) 0x08
-#define ACPI_GPE_DISPATCH_METHOD        (u8) 0x10
-#define ACPI_GPE_DISPATCH_NOT_USED      (u8) 0x00	/* Default */
+#define ACPI_GPE_DISPATCH_MASK          (u8) 0x0C
+#define ACPI_GPE_DISPATCH_HANDLER       (u8) 0x04
+#define ACPI_GPE_DISPATCH_METHOD        (u8) 0x08
+#define ACPI_GPE_DISPATCH_NOT_USED      (u8) 0x00
 
 /*
  * Flags for GPE and Lock interfaces
  */
-#define ACPI_EVENT_WAKE_ENABLE          0x2	/* acpi_gpe_enable */
-#define ACPI_EVENT_WAKE_DISABLE         0x2	/* acpi_gpe_disable */
-
 #define ACPI_NOT_ISR                    0x1
 #define ACPI_ISR                        0x0