aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evxfevnt.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-07-07 18:43:36 -0400
committerLen Brown <len.brown@intel.com>2010-07-12 14:17:39 -0400
commit9874647ba1bdf3e1af25e079070a00676f60f2f0 (patch)
tree655caf5c08b5c882ee9a8cf14766faa24f7f1a8a /drivers/acpi/acpica/evxfevnt.c
parente8e18c956152ec9c26c94c6401c174691a8f04e7 (diff)
ACPI / ACPICA: Do not execute _PRW methods during initialization
Currently, during initialization ACPICA walks the entire ACPI namespace in search of any device objects with assciated _PRW methods. All of the _PRW methods found are executed in the process to extract the GPE information returned by them, so that the GPEs in question can be marked as "able to wakeup" (more precisely, the ACPI_GPE_CAN_WAKE flag is set for them). The only purpose of this exercise is to avoid enabling the CAN_WAKE GPEs automatically, even if there are _Lxx/_Exx methods associated with them. However, it is both costly and unnecessary, because the host OS has to execute the _PRW methods anyway to check which devices can wake up the system from sleep states. Moreover, it then uses full information returned by _PRW, including the GPE information, so it can take care of disabling the GPEs if necessary. Remove the code that walks the namespace and executes _PRW from ACPICA and modify comments to reflect that change. Make acpi_bus_set_run_wake_flags() disable GPEs for wakeup devices so that they don't cause spurious wakeup events to be signaled. This not only reduces the complexity of the ACPICA initialization code, but in some cases it should reduce the kernel boot time as well. Unfortunately, for this purpose we need a new ACPICA function, acpi_gpe_can_wake(), to be called by the host OS in order to disable the GPEs that can wake up the system and were previously enabled by acpi_ev_initialize_gpe_block() or acpi_ev_update_gpes() (such a GPE should be disabled only once, because the initialization code enables it only once, but it may be pointed to by _PRW for multiple devices and that's why the additional function is necessary). 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.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index fda5b44a5567..bd06fad83e7a 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -389,6 +389,59 @@ ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
389 389
390/******************************************************************************* 390/*******************************************************************************
391 * 391 *
392 * FUNCTION: acpi_gpe_can_wake
393 *
394 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
395 * gpe_number - GPE level within the GPE block
396 *
397 * RETURN: Status
398 *
399 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
400 * has a corresponding method and is currently enabled, disable it
401 * (GPEs with corresponding methods are enabled unconditionally
402 * during initialization, but GPEs that can wake up are expected
403 * to be initially disabled).
404 *
405 ******************************************************************************/
406acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
407{
408 acpi_status status = AE_OK;
409 struct acpi_gpe_event_info *gpe_event_info;
410 acpi_cpu_flags flags;
411 u8 disable = 0;
412
413 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
414
415 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
416
417 /* Ensure that we have a valid GPE number */
418
419 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
420 if (!gpe_event_info) {
421 status = AE_BAD_PARAMETER;
422 goto unlock_and_exit;
423 }
424
425 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
426 goto unlock_and_exit;
427 }
428
429 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
430 disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
431 && gpe_event_info->runtime_count;
432
433unlock_and_exit:
434 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
435
436 if (disable)
437 status = acpi_disable_gpe(gpe_device, gpe_number);
438
439 return_ACPI_STATUS(status);
440}
441ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
442
443/*******************************************************************************
444 *
392 * FUNCTION: acpi_disable_event 445 * FUNCTION: acpi_disable_event
393 * 446 *
394 * PARAMETERS: Event - The fixed eventto be enabled 447 * PARAMETERS: Event - The fixed eventto be enabled
@@ -703,7 +756,7 @@ acpi_install_gpe_block(acpi_handle gpe_device,
703 756
704 obj_desc->device.gpe_block = gpe_block; 757 obj_desc->device.gpe_block = gpe_block;
705 758
706 /* Run the _PRW methods and enable the runtime GPEs in the new block */ 759 /* Enable the runtime GPEs in the new block */
707 760
708 status = acpi_ev_initialize_gpe_block(node, gpe_block); 761 status = acpi_ev_initialize_gpe_block(node, gpe_block);
709 762