aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evgpeblk.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/evgpeblk.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/evgpeblk.c')
-rw-r--r--drivers/acpi/acpica/evgpeblk.c47
1 files changed, 5 insertions, 42 deletions
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 0c6f3f878eb5..12ca1bc5f1fd 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -439,8 +439,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
439{ 439{
440 acpi_status status; 440 acpi_status status;
441 struct acpi_gpe_event_info *gpe_event_info; 441 struct acpi_gpe_event_info *gpe_event_info;
442 struct acpi_gpe_walk_info walk_info;
443 u32 wake_gpe_count;
444 u32 gpe_enabled_count; 442 u32 gpe_enabled_count;
445 u32 gpe_index; 443 u32 gpe_index;
446 u32 gpe_number; 444 u32 gpe_number;
@@ -456,37 +454,9 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
456 } 454 }
457 455
458 /* 456 /*
459 * Runtime option: Should wake GPEs be enabled at runtime? The default 457 * Enable all GPEs that have a corresponding method. Any other GPEs
460 * is no, they should only be enabled just as the machine goes to sleep. 458 * within this block must be enabled via the acpi_enable_gpe interface.
461 */ 459 */
462 if (acpi_gbl_leave_wake_gpes_disabled) {
463 /*
464 * Differentiate runtime vs wake GPEs, via the _PRW control methods.
465 * Each GPE that has one or more _PRWs that reference it is by
466 * definition a wake GPE and will not be enabled while the machine
467 * is running.
468 */
469 walk_info.gpe_block = gpe_block;
470 walk_info.gpe_device = gpe_device;
471 walk_info.execute_by_owner_id = FALSE;
472
473 status =
474 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
475 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
476 acpi_ev_match_prw_and_gpe, NULL,
477 &walk_info, NULL);
478 if (ACPI_FAILURE(status)) {
479 ACPI_EXCEPTION((AE_INFO, status,
480 "While executing _PRW methods"));
481 }
482 }
483
484 /*
485 * Enable all GPEs that have a corresponding method and are not
486 * capable of generating wakeups. Any other GPEs within this block
487 * must be enabled via the acpi_enable_gpe interface.
488 */
489 wake_gpe_count = 0;
490 gpe_enabled_count = 0; 460 gpe_enabled_count = 0;
491 461
492 if (gpe_device == acpi_gbl_fadt_gpe_device) { 462 if (gpe_device == acpi_gbl_fadt_gpe_device) {
@@ -512,13 +482,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
512 goto enabled; 482 goto enabled;
513 } 483 }
514 484
515 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
516 wake_gpe_count++;
517 if (acpi_gbl_leave_wake_gpes_disabled) {
518 continue;
519 }
520 }
521
522 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ 485 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
523 486
524 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { 487 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
@@ -540,10 +503,10 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
540 } 503 }
541 } 504 }
542 505
543 if (gpe_enabled_count || wake_gpe_count) { 506 if (gpe_enabled_count) {
544 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 507 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
545 "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n", 508 "Enabled %u GPEs in this block\n",
546 gpe_enabled_count, wake_gpe_count)); 509 gpe_enabled_count));
547 } 510 }
548 511
549 return_ACPI_STATUS(AE_OK); 512 return_ACPI_STATUS(AE_OK);