diff options
author | Erik Schmauss <erik.schmauss@intel.com> | 2018-03-15 00:12:59 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2018-03-18 18:52:00 +0100 |
commit | 87cd826b5979d91d4f2ba189e0652820f2da417f (patch) | |
tree | bf6d9d3f5edf4eb692af63289b2fbf6724465f8e /drivers/acpi/acpica/evxfgpe.c | |
parent | ACPICA: Events: Add parallel GPE handling support to fix potential redundant ... (diff) | |
download | linux-87cd826b5979d91d4f2ba189e0652820f2da417f.tar.xz linux-87cd826b5979d91d4f2ba189e0652820f2da417f.zip |
ACPICA: Events: Dispatch GPEs after enabling for the first time
After being enabled for the first time, the GPEs may have STS bits already
set. Setting EN bits is not sufficient to trigger the GPEs again, so this
patch polls GPEs after enabling them for the first time.
This is a cleaner version on top of the "GPE clear" fix generated according
to Mika's report and Rafael's original Linux based fix. Based on Linux
commit originated from Rafael J. Wysocki, fixed by Lv Zheng.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Erik Schmauss <erik.schmauss@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/evxfgpe.c')
-rw-r--r-- | drivers/acpi/acpica/evxfgpe.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index cbb1598df9dc..f9303444f7f7 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -77,6 +77,7 @@ ACPI_MODULE_NAME("evxfgpe") acpi_status acpi_update_all_gpes(void) { acpi_status status; + u8 is_polling_needed = FALSE; ACPI_FUNCTION_TRACE(acpi_update_all_gpes); @@ -89,7 +90,8 @@ acpi_status acpi_update_all_gpes(void) goto unlock_and_exit; } - status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); + status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, + &is_polling_needed); if (ACPI_SUCCESS(status)) { acpi_gbl_all_gpes_initialized = TRUE; } @@ -97,6 +99,12 @@ acpi_status acpi_update_all_gpes(void) unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + if (is_polling_needed && acpi_gbl_all_gpes_initialized) { + + /* Poll GPEs to handle already triggered events */ + + acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head); + } return_ACPI_STATUS(status); } @@ -135,6 +143,17 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != ACPI_GPE_DISPATCH_NONE) { status = acpi_ev_add_gpe_reference(gpe_event_info); + if (ACPI_SUCCESS(status) && + ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) { + + /* Poll edge-triggered GPEs to handle existing events */ + + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + (void)acpi_ev_detect_gpe(gpe_device, + gpe_event_info, + gpe_number); + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + } } else { status = AE_NO_HANDLER; } |