diff options
author | Len Brown <len.brown@intel.com> | 2010-10-25 02:13:09 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-10-25 02:13:09 -0400 |
commit | 6e04c417aed5b0a5bd6ae80928bbd759fa1faabc (patch) | |
tree | be657ff1734320850c2ea37d4336b576f07dca31 /drivers/acpi | |
parent | 880308089d0abebac365c3a1378b4e3238b100ac (diff) | |
parent | a210080195c95ebca2a517ee3057d71607aa65e0 (diff) |
Merge branch 'gpe-defer' into release
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 5 | ||||
-rw-r--r-- | drivers/acpi/acpica/acglobal.h | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 3 | ||||
-rw-r--r-- | drivers/acpi/acpica/evevent.c | 41 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 47 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeinit.c | 31 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxface.c | 19 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 61 | ||||
-rw-r--r-- | drivers/acpi/acpica/utglobal.c | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/utxface.c | 13 | ||||
-rw-r--r-- | drivers/acpi/dock.c | 1 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 9 |
12 files changed, 92 insertions, 140 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 36867cd70eac..a6f99cc37a19 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
105 | struct acpi_gpe_block_info **return_gpe_block); | 105 | struct acpi_gpe_block_info **return_gpe_block); |
106 | 106 | ||
107 | acpi_status | 107 | acpi_status |
108 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
109 | struct acpi_gpe_block_info *gpe_block); | 109 | struct acpi_gpe_block_info *gpe_block, |
110 | void *ignored); | ||
110 | 111 | ||
111 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); | 112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); |
112 | 113 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index b8dbb9bd6962..ad88fcae4eb9 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -370,6 +370,7 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
370 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 370 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
371 | ACPI_EXTERN struct acpi_gpe_block_info | 371 | ACPI_EXTERN struct acpi_gpe_block_info |
372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
373 | ACPI_EXTERN u8 acpi_all_gpes_initialized; | ||
373 | 374 | ||
374 | /***************************************************************************** | 375 | /***************************************************************************** |
375 | * | 376 | * |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 8acf1e8e479f..2ceb0c05b2d7 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -413,6 +413,7 @@ struct acpi_handler_info { | |||
413 | void *context; /* Context to be passed to handler */ | 413 | void *context; /* Context to be passed to handler */ |
414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ | 414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ |
415 | u8 orig_flags; /* Original misc info about this GPE */ | 415 | u8 orig_flags; /* Original misc info about this GPE */ |
416 | u8 orig_enabled; /* Set if the GPE was originally enabled */ | ||
416 | }; | 417 | }; |
417 | 418 | ||
418 | union acpi_gpe_dispatch_info { | 419 | union acpi_gpe_dispatch_info { |
@@ -457,6 +458,7 @@ struct acpi_gpe_block_info { | |||
457 | u32 register_count; /* Number of register pairs in block */ | 458 | u32 register_count; /* Number of register pairs in block */ |
458 | u16 gpe_count; /* Number of individual GPEs in block */ | 459 | u16 gpe_count; /* Number of individual GPEs in block */ |
459 | u8 block_base_number; /* Base GPE number for this block */ | 460 | u8 block_base_number; /* Base GPE number for this block */ |
461 | u8 initialized; /* If set, the GPE block has been initialized */ | ||
460 | }; | 462 | }; |
461 | 463 | ||
462 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 464 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
@@ -473,7 +475,6 @@ struct acpi_gpe_walk_info { | |||
473 | struct acpi_gpe_block_info *gpe_block; | 475 | struct acpi_gpe_block_info *gpe_block; |
474 | u16 count; | 476 | u16 count; |
475 | acpi_owner_id owner_id; | 477 | acpi_owner_id owner_id; |
476 | u8 enable_this_gpe; | ||
477 | u8 execute_by_owner_id; | 478 | u8 execute_by_owner_id; |
478 | }; | 479 | }; |
479 | 480 | ||
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index 303618889da0..c61c3039c31a 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -95,47 +95,6 @@ acpi_status acpi_ev_initialize_events(void) | |||
95 | 95 | ||
96 | /******************************************************************************* | 96 | /******************************************************************************* |
97 | * | 97 | * |
98 | * FUNCTION: acpi_ev_install_fadt_gpes | ||
99 | * | ||
100 | * PARAMETERS: None | ||
101 | * | ||
102 | * RETURN: Status | ||
103 | * | ||
104 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks | ||
105 | * (0 and 1). The HW must be fully initialized at this point, | ||
106 | * including global lock support. | ||
107 | * | ||
108 | ******************************************************************************/ | ||
109 | |||
110 | acpi_status acpi_ev_install_fadt_gpes(void) | ||
111 | { | ||
112 | acpi_status status; | ||
113 | |||
114 | ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); | ||
115 | |||
116 | /* Namespace must be locked */ | ||
117 | |||
118 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return (status); | ||
121 | } | ||
122 | |||
123 | /* FADT GPE Block 0 */ | ||
124 | |||
125 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | ||
126 | acpi_gbl_gpe_fadt_blocks[0]); | ||
127 | |||
128 | /* FADT GPE Block 1 */ | ||
129 | |||
130 | (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, | ||
131 | acpi_gbl_gpe_fadt_blocks[1]); | ||
132 | |||
133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
134 | return_ACPI_STATUS(AE_OK); | ||
135 | } | ||
136 | |||
137 | /******************************************************************************* | ||
138 | * | ||
139 | * FUNCTION: acpi_ev_install_xrupt_handlers | 98 | * FUNCTION: acpi_ev_install_xrupt_handlers |
140 | * | 99 | * |
141 | * PARAMETERS: None | 100 | * PARAMETERS: None |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 85445fb5844e..020add3eee1c 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -363,6 +363,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->register_count = register_count; | 364 | gpe_block->register_count = register_count; |
365 | gpe_block->block_base_number = gpe_block_base_number; | 365 | gpe_block->block_base_number = gpe_block_base_number; |
366 | gpe_block->initialized = FALSE; | ||
366 | 367 | ||
367 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | 368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, |
368 | sizeof(struct acpi_generic_address)); | 369 | sizeof(struct acpi_generic_address)); |
@@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
387 | 388 | ||
389 | acpi_all_gpes_initialized = FALSE; | ||
390 | |||
388 | /* Find all GPE methods (_Lxx or_Exx) for this block */ | 391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ |
389 | 392 | ||
390 | walk_info.gpe_block = gpe_block; | 393 | walk_info.gpe_block = gpe_block; |
391 | walk_info.gpe_device = gpe_device; | 394 | walk_info.gpe_device = gpe_device; |
392 | walk_info.enable_this_gpe = FALSE; | ||
393 | walk_info.execute_by_owner_id = FALSE; | 395 | walk_info.execute_by_owner_id = FALSE; |
394 | 396 | ||
395 | status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, | 397 | status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, |
@@ -434,35 +436,34 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
434 | ******************************************************************************/ | 436 | ******************************************************************************/ |
435 | 437 | ||
436 | acpi_status | 438 | acpi_status |
437 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 439 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
438 | struct acpi_gpe_block_info *gpe_block) | 440 | struct acpi_gpe_block_info *gpe_block, |
441 | void *ignored) | ||
439 | { | 442 | { |
440 | acpi_status status; | 443 | acpi_status status; |
441 | struct acpi_gpe_event_info *gpe_event_info; | 444 | struct acpi_gpe_event_info *gpe_event_info; |
442 | u32 gpe_enabled_count; | 445 | u32 gpe_enabled_count; |
443 | u32 gpe_index; | 446 | u32 gpe_index; |
444 | u32 gpe_number; | ||
445 | u32 i; | 447 | u32 i; |
446 | u32 j; | 448 | u32 j; |
447 | 449 | ||
448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); | 450 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); |
449 | 451 | ||
450 | /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ | 452 | /* |
451 | 453 | * Ignore a null GPE block (e.g., if no GPE block 1 exists) and | |
452 | if (!gpe_block) { | 454 | * GPE blocks that have been initialized already. |
455 | */ | ||
456 | if (!gpe_block || gpe_block->initialized) { | ||
453 | return_ACPI_STATUS(AE_OK); | 457 | return_ACPI_STATUS(AE_OK); |
454 | } | 458 | } |
455 | 459 | ||
456 | /* | 460 | /* |
457 | * Enable all GPEs that have a corresponding method. Any other GPEs | 461 | * Enable all GPEs that have a corresponding method and have the |
458 | * within this block must be enabled via the acpi_enable_gpe interface. | 462 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must |
463 | * be enabled via the acpi_enable_gpe() interface. | ||
459 | */ | 464 | */ |
460 | gpe_enabled_count = 0; | 465 | gpe_enabled_count = 0; |
461 | 466 | ||
462 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
463 | gpe_device = NULL; | ||
464 | } | ||
465 | |||
466 | for (i = 0; i < gpe_block->register_count; i++) { | 467 | for (i = 0; i < gpe_block->register_count; i++) { |
467 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | 468 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
468 | 469 | ||
@@ -470,27 +471,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
470 | 471 | ||
471 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 472 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
472 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 473 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
473 | gpe_number = gpe_index + gpe_block->block_base_number; | ||
474 | 474 | ||
475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | 475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ |
476 | 476 | ||
477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { | 477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) |
478 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
478 | continue; | 479 | continue; |
479 | } | 480 | } |
480 | 481 | ||
481 | /* | 482 | status = acpi_raw_enable_gpe(gpe_event_info); |
482 | * If the GPE has already been enabled for runtime | ||
483 | * signaling, make sure it remains enabled, but do not | ||
484 | * increment its reference counter. | ||
485 | */ | ||
486 | status = gpe_event_info->runtime_count ? | ||
487 | acpi_ev_enable_gpe(gpe_event_info) : | ||
488 | acpi_enable_gpe(gpe_device, gpe_number); | ||
489 | |||
490 | if (ACPI_FAILURE(status)) { | 483 | if (ACPI_FAILURE(status)) { |
491 | ACPI_EXCEPTION((AE_INFO, status, | 484 | ACPI_EXCEPTION((AE_INFO, status, |
492 | "Could not enable GPE 0x%02X", | 485 | "Could not enable GPE 0x%02X", |
493 | gpe_number)); | 486 | gpe_index + gpe_block->block_base_number)); |
494 | continue; | 487 | continue; |
495 | } | 488 | } |
496 | 489 | ||
@@ -504,5 +497,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
504 | gpe_enabled_count)); | 497 | gpe_enabled_count)); |
505 | } | 498 | } |
506 | 499 | ||
500 | gpe_block->initialized = TRUE; | ||
501 | |||
507 | return_ACPI_STATUS(AE_OK); | 502 | return_ACPI_STATUS(AE_OK); |
508 | } | 503 | } |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 3084c5de1bba..2c7def95f721 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
210 | * | 210 | * |
211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a | 211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a |
212 | * result of a Load() or load_table() operation. If new GPE | 212 | * result of a Load() or load_table() operation. If new GPE |
213 | * methods have been installed, register the new methods and | 213 | * methods have been installed, register the new methods. |
214 | * enable and runtime GPEs that are associated with them. | ||
215 | * | 214 | * |
216 | ******************************************************************************/ | 215 | ******************************************************************************/ |
217 | 216 | ||
@@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
239 | walk_info.owner_id = table_owner_id; | 238 | walk_info.owner_id = table_owner_id; |
240 | walk_info.execute_by_owner_id = TRUE; | 239 | walk_info.execute_by_owner_id = TRUE; |
241 | walk_info.count = 0; | 240 | walk_info.count = 0; |
242 | walk_info.enable_this_gpe = TRUE; | ||
243 | 241 | ||
244 | /* Walk the interrupt level descriptor list */ | 242 | /* Walk the interrupt level descriptor list */ |
245 | 243 | ||
@@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
301 | * | 299 | * |
302 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods | 300 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods |
303 | * with that owner. | 301 | * with that owner. |
304 | * If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE | ||
305 | * method is immediately enabled (Used for Load/load_table operators) | ||
306 | * | 302 | * |
307 | ******************************************************************************/ | 303 | ******************************************************************************/ |
308 | 304 | ||
@@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
315 | struct acpi_gpe_walk_info *walk_info = | 311 | struct acpi_gpe_walk_info *walk_info = |
316 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); | 312 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); |
317 | struct acpi_gpe_event_info *gpe_event_info; | 313 | struct acpi_gpe_event_info *gpe_event_info; |
318 | struct acpi_namespace_node *gpe_device; | ||
319 | acpi_status status; | ||
320 | u32 gpe_number; | 314 | u32 gpe_number; |
321 | char name[ACPI_NAME_SIZE + 1]; | 315 | char name[ACPI_NAME_SIZE + 1]; |
322 | u8 type; | 316 | u8 type; |
@@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
421 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); | 415 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); |
422 | gpe_event_info->dispatch.method_node = method_node; | 416 | gpe_event_info->dispatch.method_node = method_node; |
423 | 417 | ||
424 | /* | ||
425 | * Enable this GPE if requested. This only happens when during the | ||
426 | * execution of a Load or load_table operator. We have found a new | ||
427 | * GPE method and want to immediately enable the GPE if it is a | ||
428 | * runtime GPE. | ||
429 | */ | ||
430 | if (walk_info->enable_this_gpe) { | ||
431 | |||
432 | walk_info->count++; | ||
433 | gpe_device = walk_info->gpe_device; | ||
434 | |||
435 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
436 | gpe_device = NULL; | ||
437 | } | ||
438 | |||
439 | status = acpi_enable_gpe(gpe_device, gpe_number); | ||
440 | if (ACPI_FAILURE(status)) { | ||
441 | ACPI_EXCEPTION((AE_INFO, status, | ||
442 | "Could not enable GPE 0x%02X", | ||
443 | gpe_number)); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, | 418 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, |
448 | "Registered GPE method %s as GPE number 0x%.2X\n", | 419 | "Registered GPE method %s as GPE number 0x%.2X\n", |
449 | name, gpe_number)); | 420 | name, gpe_number)); |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 14e48add32fa..36af222cac65 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -726,15 +726,16 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
727 | 727 | ||
728 | /* | 728 | /* |
729 | * If the GPE is associated with a method and it cannot wake up the | 729 | * If the GPE is associated with a method, it might have been enabled |
730 | * system from sleep states, it was enabled automatically during | 730 | * automatically during initialization, in which case it has to be |
731 | * initialization, so it has to be disabled now to avoid spurious | 731 | * disabled now to avoid spurious execution of the handler. |
732 | * execution of the handler. | ||
733 | */ | 732 | */ |
734 | 733 | ||
735 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 734 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) |
736 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | 735 | && gpe_event_info->runtime_count) { |
736 | handler->orig_enabled = 1; | ||
737 | (void)acpi_raw_disable_gpe(gpe_event_info); | 737 | (void)acpi_raw_disable_gpe(gpe_event_info); |
738 | } | ||
738 | 739 | ||
739 | /* Install the handler */ | 740 | /* Install the handler */ |
740 | 741 | ||
@@ -837,13 +838,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
837 | gpe_event_info->flags |= handler->orig_flags; | 838 | gpe_event_info->flags |= handler->orig_flags; |
838 | 839 | ||
839 | /* | 840 | /* |
840 | * If the GPE was previously associated with a method and it cannot wake | 841 | * If the GPE was previously associated with a method and it was |
841 | * up the system from sleep states, it should be enabled at this point | 842 | * enabled, it should be enabled at this point to restore the |
842 | * to restore the post-initialization configuration. | 843 | * post-initialization configuration. |
843 | */ | 844 | */ |
844 | 845 | ||
845 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 846 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) |
846 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | 847 | && handler->orig_enabled) |
847 | (void)acpi_raw_enable_gpe(gpe_event_info); | 848 | (void)acpi_raw_enable_gpe(gpe_event_info); |
848 | 849 | ||
849 | /* Now we can free the handler object */ | 850 | /* Now we can free the handler object */ |
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) | |||
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 | } | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 4a5dcaa268de..e87bc6760be6 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -768,6 +768,7 @@ acpi_status acpi_ut_init_globals(void) | |||
768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
770 | acpi_current_gpe_count = 0; | 770 | acpi_current_gpe_count = 0; |
771 | acpi_all_gpes_initialized = FALSE; | ||
771 | 772 | ||
772 | /* Global handlers */ | 773 | /* Global handlers */ |
773 | 774 | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index c2da90f5fbe9..1f484c9a6888 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -299,19 +299,6 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
299 | } | 299 | } |
300 | 300 | ||
301 | /* | 301 | /* |
302 | * Complete the GPE initialization for the GPE blocks defined in the FADT | ||
303 | * (GPE block 0 and 1). | ||
304 | * | ||
305 | * NOTE: Currently, there seems to be no need to run the _REG methods | ||
306 | * before enabling the GPEs. | ||
307 | */ | ||
308 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
309 | status = acpi_ev_install_fadt_gpes(); | ||
310 | if (ACPI_FAILURE(status)) | ||
311 | return (status); | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Empty the caches (delete the cached objects) on the assumption that | 302 | * Empty the caches (delete the cached objects) on the assumption that |
316 | * the table load filled them up more than they will be at runtime -- | 303 | * the table load filled them up more than they will be at runtime -- |
317 | * thus wasting non-paged memory. | 304 | * thus wasting non-paged memory. |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3fe29e992be8..44f99bd83741 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
725 | complete_dock(ds); | 725 | complete_dock(ds); |
726 | dock_event(ds, event, DOCK_EVENT); | 726 | dock_event(ds, event, DOCK_EVENT); |
727 | dock_lock(ds, 1); | 727 | dock_lock(ds, 1); |
728 | acpi_update_gpes(); | ||
728 | break; | 729 | break; |
729 | } | 730 | } |
730 | if (dock_present(ds) || dock_in_progress(ds)) | 731 | if (dock_present(ds) || dock_in_progress(ds)) |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 6155eeb2e89a..2b6c21d86b98 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1434,6 +1434,7 @@ EXPORT_SYMBOL(acpi_bus_add); | |||
1434 | int acpi_bus_start(struct acpi_device *device) | 1434 | int acpi_bus_start(struct acpi_device *device) |
1435 | { | 1435 | { |
1436 | struct acpi_bus_ops ops; | 1436 | struct acpi_bus_ops ops; |
1437 | int result; | ||
1437 | 1438 | ||
1438 | if (!device) | 1439 | if (!device) |
1439 | return -EINVAL; | 1440 | return -EINVAL; |
@@ -1441,7 +1442,11 @@ int acpi_bus_start(struct acpi_device *device) | |||
1441 | memset(&ops, 0, sizeof(ops)); | 1442 | memset(&ops, 0, sizeof(ops)); |
1442 | ops.acpi_op_start = 1; | 1443 | ops.acpi_op_start = 1; |
1443 | 1444 | ||
1444 | return acpi_bus_scan(device->handle, &ops, NULL); | 1445 | result = acpi_bus_scan(device->handle, &ops, NULL); |
1446 | |||
1447 | acpi_update_gpes(); | ||
1448 | |||
1449 | return result; | ||
1445 | } | 1450 | } |
1446 | EXPORT_SYMBOL(acpi_bus_start); | 1451 | EXPORT_SYMBOL(acpi_bus_start); |
1447 | 1452 | ||
@@ -1555,6 +1560,8 @@ int __init acpi_scan_init(void) | |||
1555 | 1560 | ||
1556 | if (result) | 1561 | if (result) |
1557 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1562 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1563 | else | ||
1564 | acpi_update_gpes(); | ||
1558 | 1565 | ||
1559 | return result; | 1566 | return result; |
1560 | } | 1567 | } |