Clearing the status bit means OSPM acknowledges the GPE and the hardware then can bring follow-up events up. Acklowdging it too early causes OSPM seeing level triggered GPE storms or missing edge-triggered GPEs if the OSPM driver responds slowly. Some drivers may choose to implement GPE condition clearing code in a position that is different from where it should be disabled or re-enabled, in which case, the internal auto GPE clearing operations should be abandoned. This flag facilitates such driver designs and implementations. Note that drivers will need to invoke acpi_clear_gpe() manually in a proper position where the causes and conditions of the GPE have been solved and the GPE status can be safely cleared. Lv Zheng. Signed-off-by: Lv Zheng <lv.zheng@xxxxxxxxx> --- drivers/acpi/acpica/evgpe.c | 6 ++++-- include/acpi/actypes.h | 16 +++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 64f6d41..7589956 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -633,7 +633,8 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info * gpe_event_info) { acpi_status status; - if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == + if (!(gpe_event_info->flags & ACPI_GPE_NO_AUTO_CLEAR) && + (gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) { /* * GPE is level-triggered, we clear the GPE status bit after @@ -719,7 +720,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, * 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) == + if (!(gpe_event_info->flags & ACPI_GPE_NO_AUTO_CLEAR) && + (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)) { diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 608a040..18f341f 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -738,13 +738,14 @@ typedef u32 acpi_event_status; /* * GPE info flags - Per GPE - * +-------+-+-+---+ - * | 7:4 |3|2|1:0| - * +-------+-+-+---+ - * | | | | - * | | | +-- Type of dispatch:to method, handler, notify, or none - * | | +----- Interrupt type: edge or level triggered - * | +------- Is a Wake GPE + * +-------+-+-+-+---+ + * | 7:5 |4|3|2|1:0| + * +-------+-+-+-+---+ + * | | | | | + * | | | | +-- Type of dispatch:to method, handler, notify, or none + * | | | +----- Interrupt type: edge or level triggered + * | | +------- Is a Wake GPE + * | +--------- Do not clear GPE automatically * +------------ <Reserved> */ #define ACPI_GPE_DISPATCH_NONE (u8) 0x00 @@ -758,6 +759,7 @@ typedef u32 acpi_event_status; #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x04 #define ACPI_GPE_CAN_WAKE (u8) 0x08 +#define ACPI_GPE_NO_AUTO_CLEAR (u8) 0x10 /* * Flags for GPE and Lock interfaces -- 1.7.10 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html