aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2010-10-25 02:13:09 -0400
committerLen Brown <len.brown@intel.com>2010-10-25 02:13:09 -0400
commit6e04c417aed5b0a5bd6ae80928bbd759fa1faabc (patch)
treebe657ff1734320850c2ea37d4336b576f07dca31
parent880308089d0abebac365c3a1378b4e3238b100ac (diff)
parenta210080195c95ebca2a517ee3057d71607aa65e0 (diff)
Merge branch 'gpe-defer' into release
-rw-r--r--drivers/acpi/acpica/acevents.h5
-rw-r--r--drivers/acpi/acpica/acglobal.h1
-rw-r--r--drivers/acpi/acpica/aclocal.h3
-rw-r--r--drivers/acpi/acpica/evevent.c41
-rw-r--r--drivers/acpi/acpica/evgpeblk.c47
-rw-r--r--drivers/acpi/acpica/evgpeinit.c31
-rw-r--r--drivers/acpi/acpica/evxface.c19
-rw-r--r--drivers/acpi/acpica/evxfevnt.c61
-rw-r--r--drivers/acpi/acpica/utglobal.c1
-rw-r--r--drivers/acpi/acpica/utxface.c13
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/acpi/scan.c9
-rw-r--r--include/acpi/acpixf.h2
13 files changed, 94 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
107acpi_status 107acpi_status
108acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 108acpi_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
111acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); 112acpi_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
370ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; 370ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
371ACPI_EXTERN struct acpi_gpe_block_info 371ACPI_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];
373ACPI_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
418union acpi_gpe_dispatch_info { 419union 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
110acpi_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
436acpi_status 438acpi_status
437acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 439acpi_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
396unlock_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
931acpi_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
949unlock:
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);
1434int acpi_bus_start(struct acpi_device *device) 1434int 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}
1446EXPORT_SYMBOL(acpi_bus_start); 1451EXPORT_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}
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 7db647c96283..53b7cfd924a3 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -315,6 +315,8 @@ acpi_install_gpe_block(acpi_handle gpe_device,
315 315
316acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); 316acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
317 317
318acpi_status acpi_update_gpes(void);
319
318/* 320/*
319 * Resource interfaces 321 * Resource interfaces
320 */ 322 */