diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-09-15 18:30:43 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-09-24 16:55:47 -0400 |
commit | a210080195c95ebca2a517ee3057d71607aa65e0 (patch) | |
tree | 96aa2aee4b9bdbc747b7a0d7150d0b41650ebe90 /drivers/acpi/acpica/evxfevnt.c | |
parent | 2422084a94fcd5038406261b331672a13c92c050 (diff) |
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 304825528d4..a1dabe3fd8a 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) | |||
379 | /* Ensure that we have a valid GPE number */ | 379 | /* Ensure that we have a valid GPE number */ |
380 | 380 | ||
381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
382 | if (!gpe_event_info) { | 382 | if (gpe_event_info) { |
383 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
384 | } else { | ||
383 | status = AE_BAD_PARAMETER; | 385 | status = AE_BAD_PARAMETER; |
384 | goto unlock_and_exit; | ||
385 | } | ||
386 | |||
387 | if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { | ||
388 | goto unlock_and_exit; | ||
389 | } | 386 | } |
390 | 387 | ||
391 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
392 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { | ||
393 | (void)acpi_raw_disable_gpe(gpe_event_info); | ||
394 | } | ||
395 | |||
396 | unlock_and_exit: | ||
397 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
398 | return_ACPI_STATUS(status); | 389 | return_ACPI_STATUS(status); |
399 | } | 390 | } |
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
651 | struct acpi_generic_address *gpe_block_address, | 642 | struct acpi_generic_address *gpe_block_address, |
652 | u32 register_count, u32 interrupt_number) | 643 | u32 register_count, u32 interrupt_number) |
653 | { | 644 | { |
654 | acpi_status status; | 645 | acpi_status status = AE_OK; |
655 | union acpi_operand_object *obj_desc; | 646 | union acpi_operand_object *obj_desc; |
656 | struct acpi_namespace_node *node; | 647 | struct acpi_namespace_node *node; |
657 | struct acpi_gpe_block_info *gpe_block; | 648 | struct acpi_gpe_block_info *gpe_block; |
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
715 | 706 | ||
716 | obj_desc->device.gpe_block = gpe_block; | 707 | obj_desc->device.gpe_block = gpe_block; |
717 | 708 | ||
718 | /* Enable the runtime GPEs in the new block */ | ||
719 | |||
720 | status = acpi_ev_initialize_gpe_block(node, gpe_block); | ||
721 | |||
722 | unlock_and_exit: | 709 | unlock_and_exit: |
723 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 710 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
724 | return_ACPI_STATUS(status); | 711 | return_ACPI_STATUS(status); |
@@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpes(void) | |||
924 | 911 | ||
925 | return_ACPI_STATUS(status); | 912 | return_ACPI_STATUS(status); |
926 | } | 913 | } |
914 | |||
915 | /****************************************************************************** | ||
916 | * | ||
917 | * FUNCTION: acpi_update_gpes | ||
918 | * | ||
919 | * PARAMETERS: None | ||
920 | * | ||
921 | * RETURN: None | ||
922 | * | ||
923 | * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and | ||
924 | * are not pointed to by any device _PRW methods indicating that | ||
925 | * these GPEs are generally intended for system or device wakeup | ||
926 | * (such GPEs have to be enabled directly when the devices whose | ||
927 | * _PRW methods point to them are set up for wakeup signaling). | ||
928 | * | ||
929 | ******************************************************************************/ | ||
930 | |||
931 | acpi_status acpi_update_gpes(void) | ||
932 | { | ||
933 | acpi_status status; | ||
934 | |||
935 | ACPI_FUNCTION_TRACE(acpi_update_gpes); | ||
936 | |||
937 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
938 | if (ACPI_FAILURE(status)) { | ||
939 | return_ACPI_STATUS(status); | ||
940 | } else if (acpi_all_gpes_initialized) { | ||
941 | goto unlock; | ||
942 | } | ||
943 | |||
944 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
945 | if (ACPI_SUCCESS(status)) { | ||
946 | acpi_all_gpes_initialized = TRUE; | ||
947 | } | ||
948 | |||
949 | unlock: | ||
950 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
951 | |||
952 | return_ACPI_STATUS(status); | ||
953 | } | ||