acpi_status
 acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info);
 
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
-                  u8 write_to_hardware);
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
 
 
  * FUNCTION:    acpi_ev_enable_gpe
  *
  * PARAMETERS:  gpe_event_info          - GPE to enable
- *              write_to_hardware       - Enable now, or just mark data structs
- *                                        (WAKE GPEs should be deferred)
  *
  * RETURN:      Status
  *
  *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info,
-                  u8 write_to_hardware)
+acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
 {
        acpi_status status;
 
 
        /* Mark wake-enabled or HW enable, or both */
 
-       if (gpe_event_info->runtime_count && write_to_hardware) {
+       if (gpe_event_info->runtime_count) {
                /* Clear the GPE (of stale events), then enable it */
                status = acpi_hw_clear_gpe(gpe_event_info);
                if (ACPI_FAILURE(status))
 
        /* Set the GPE flags for return to enabled state */
 
-       (void)acpi_ev_enable_gpe(gpe_event_info, FALSE);
+       (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
 
        /*
         * Take a snapshot of the GPE info for this level - we copy the info to
 
 
        switch (action) {
        case ACPI_GPE_ENABLE:
-               status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
+               status = acpi_ev_enable_gpe(gpe_event_info);
                break;
 
        case ACPI_GPE_DISABLE:
 
        ACPI_FUNCTION_TRACE(acpi_enable_gpe);
 
+       if (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 */
        }
 
        if (type & ACPI_GPE_TYPE_RUNTIME) {
-               if (++gpe_event_info->runtime_count == 1)
-                       status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
-
-               if (ACPI_FAILURE(status))
-                       gpe_event_info->runtime_count--;
+               if (++gpe_event_info->runtime_count == 1) {
+                       status = acpi_ev_enable_gpe(gpe_event_info);
+                       if (ACPI_FAILURE(status))
+                               gpe_event_info->runtime_count--;
+               }
        }
 
        if (type & ACPI_GPE_TYPE_WAKE) {
 
        ACPI_FUNCTION_TRACE(acpi_disable_gpe);
 
+       if (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 */
 
                goto unlock_and_exit;
        }
 
-       if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) {
+       if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
                if (--gpe_event_info->runtime_count == 0)
-                       acpi_ev_disable_gpe(gpe_event_info);
+                       status = acpi_ev_disable_gpe(gpe_event_info);
        }
 
-       if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) {
+       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.
 
        pr_debug(PREFIX "transaction start\n");
        /* disable GPE during transaction if storm is detected */
        if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+               /*
+                * It has to be disabled at the hardware level regardless of the
+                * GPE reference counting, so that it doesn't trigger.
+                */
                acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
        }
 
        ec_check_sci_sync(ec, acpi_ec_read_status(ec));
        if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
                msleep(1);
-               /* it is safe to enable GPE outside of transaction */
+               /*
+                * It is safe to enable the GPE outside of the transaction.  Use
+                * acpi_set_gpe() for that, since we used it to disable the GPE
+                * above.
+                */
                acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
        } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
                pr_info(PREFIX "GPE storm detected, "
 static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
 {
        struct acpi_ec *ec = acpi_driver_data(device);
-       /* Stop using GPE */
+       /* Stop using the GPE, but keep it reference counted. */
        acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE);
        return 0;
 }
 static int acpi_ec_resume(struct acpi_device *device)
 {
        struct acpi_ec *ec = acpi_driver_data(device);
-       /* Enable use of GPE back */
+       /* Enable the GPE again, but don't reference count it once more. */
        acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE);
        return 0;
 }