From 6ec5e12074b42fafec2a340d72e8d8e1fd4c5405 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:42:31 +0800 Subject: [PATCH] ACPICA: Events: Fix edge-triggered GPE by disabling before acknowledging it. Due to ACPI specificiation 5, chapter 5.6.4 General-Purpose Event Handling, OSPMs need to disable GPE before clearing the status bit for edge-triggered GPEs. Signed-off-by: Lv Zheng Tested-by: Gareth Williams Tested-by: Steffen Weber Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evgpe.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 48f70013b488..e4ba4dec86af 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, acpi_gbl_global_event_handler_context); } - /* - * If edge-triggered, clear the GPE status bit now. Note that - * level-triggered events are cleared after the GPE is serviced. - */ - if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == - ACPI_GPE_EDGE_TRIGGERED) { - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Unable to clear GPE %02X", - gpe_number)); - return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); - } - } - /* * Always disable the GPE so that it does not keep firing before * any asynchronous activity completes (either from the execution @@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } + /* + * If edge-triggered, clear the GPE status bit now. Note that + * level-triggered events are cleared after the GPE is serviced. + */ + if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == + ACPI_GPE_EDGE_TRIGGERED) { + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Unable to clear GPE %02X", + gpe_number)); + (void)acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_CONDITIONAL_ENABLE); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); + } + } + /* * Dispatch the GPE to either an installed handler or the control * method associated with this GPE (_Lxx or _Exx). If a handler -- 2.20.1