diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-09-16 00:30:43 +0200 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-09-24 22:55:47 +0200 |
commit | a210080195c95ebca2a517ee3057d71607aa65e0 (patch) | |
tree | 96aa2aee4b9bdbc747b7a0d7150d0b41650ebe90 /drivers/acpi/acpica/evxfevnt.c | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mat... (diff) | |
download | linux-a210080195c95ebca2a517ee3057d71607aa65e0.tar.xz linux-a210080195c95ebca2a517ee3057d71607aa65e0.zip |
ACPI / ACPICA: Defer enabling of runtime GPEs (v3)
The current ACPI GPEs initialization code has a problem that it
enables some GPEs pointed to by device _PRW methods, generally
intended for signaling wakeup events (system or device wakeup).
These GPEs are then almost immediately disabled by the ACPI namespace
scanning code with the help of acpi_gpe_can_wake(), but it would be
better not to enable them at all until really necessary.
Modify the initialization of GPEs so that the ones that have
associated _Lxx or _Exx methods and are not pointed to by any _PRW
methods will be enabled after the namespace scan is complete.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/evxfevnt.c')
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 304825528d48..a1dabe3fd8ae 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (!gpe_event_info) { + if (gpe_event_info) { + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + } else { status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { - goto unlock_and_exit; } - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { - (void)acpi_raw_disable_gpe(gpe_event_info); - } - -unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, struct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; struct acpi_gpe_block_info *gpe_block; @@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_device, obj_desc->device.gpe_block = gpe_block; - /* Enable the runtime GPEs in the new block */ - - status = acpi_ev_initialize_gpe_block(node, gpe_block); - unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(status); @@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void) return_ACPI_STATUS(status); } + +/****************************************************************************** + * + * FUNCTION: acpi_update_gpes + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and + * are not pointed to by any device _PRW methods indicating that + * these GPEs are generally intended for system or device wakeup + * (such GPEs have to be enabled directly when the devices whose + * _PRW methods point to them are set up for wakeup signaling). + * + ******************************************************************************/ + +acpi_status acpi_update_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_update_gpes); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } else if (acpi_all_gpes_initialized) { + goto unlock; + } + + status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); + if (ACPI_SUCCESS(status)) { + acpi_all_gpes_initialized = TRUE; + } + +unlock: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + + return_ACPI_STATUS(status); +} |