aboutsummaryrefslogtreecommitdiff
path: root/drivers/acpi/events
diff options
context:
space:
mode:
authorAlexey Starikovskiy <astarikovskiy@suse.de>2007-11-13 13:05:45 +0300
committerLen Brown <len.brown@intel.com>2007-12-06 21:54:43 -0500
commit17bc54eef91df29f0a22e8a1562a404cf7a68e74 (patch)
tree48f6f26a243789582721e2a3419346ea22a6dcc9 /drivers/acpi/events
parentf194d132e4971111f85c18c96067acffb13cee6d (diff)
ACPI: Defer enabling of level GPE until all pending notifies done
Level GPE should not be enabled until all work caused by it is done, e.g. all Notify() methods are completed. This can be accomplished by appending enable_gpe function to the end of notify queue. Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Acked-by: Shaohua Li <shaohua.li@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r--drivers/acpi/events/evgpe.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index e22f4a973c0..b4509f93ff8 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -501,6 +501,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
* an interrupt handler.
*
******************************************************************************/
+static void acpi_ev_asynch_enable_gpe(void *context);
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
@@ -576,22 +577,30 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
method_node)));
}
}
+ /* Defer enabling of GPE until all notify handlers are done */
+ acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
+ gpe_event_info);
+ return_VOID;
+}
- if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+static void acpi_ev_asynch_enable_gpe(void *context)
+{
+ struct acpi_gpe_event_info *gpe_event_info = context;
+ acpi_status status;
+ if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_LEVEL_TRIGGERED) {
/*
* GPE is level-triggered, we clear the GPE status bit after
* handling the event.
*/
- status = acpi_hw_clear_gpe(&local_gpe_event_info);
+ status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
return_VOID;
}
}
/* Enable this GPE */
-
- (void)acpi_hw_write_gpe_enable_reg(&local_gpe_event_info);
+ (void)acpi_hw_write_gpe_enable_reg(gpe_event_info);
return_VOID;
}