ACPI / ACPICA: Defer enabling of runtime GPEs
Subsystems (2)
PATCH 1/1 ACPI / ACPICA: Defer enabling of runtime GPEs
Bob, Matthew,
The patch below implements the idea we've been recently discussing off-list, to only enable "runtime" GPEs after the ACPI namespace have been scanned and we know what GPEs are pointed to by _PRW methods.
It is on top of the current mainline Linux kernel (2.6.36-rc2+) which contains my patches that removed the _PRW scan from the ACPICA code and modified the GPE handler installation/removal.
Fortunately, the patch turns out to be rather straightforward, although I have one reservation. Namely, I'm not sure if any GPEs can be added after acpi_scan_init() has returned, in which case we may want to enable them as soon as they are found and some code to do that will be necessary.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: ACPI / ACPICA: Defer enabling of runtime GPEs
The current ACPI GPEs initialization code has a problem that it enables some GPEs pointed to by device _PRW methods and are 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 no 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.
--- drivers/acpi/acpica/acevents.h | 5 ++- drivers/acpi/acpica/aclocal.h | 2 - drivers/acpi/acpica/evevent.c | 41 ----------------------------- drivers/acpi/acpica/evgpeblk.c | 34 ++++++++---------------- drivers/acpi/acpica/evgpeinit.c | 28 -------------------- drivers/acpi/acpica/evxface.c | 19 +++++++------ drivers/acpi/acpica/evxfevnt.c | 55 +++++++++++++++++++++++++++------------- drivers/acpi/acpica/utxface.c | 13 --------- drivers/acpi/bus.c | 1 include/acpi/acpixf.h | 2 + 10 files changed, 66 insertions(+), 134 deletions(-)
drivers/acpi/acpica/evxfevnt.c +38 -17
@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handl/* Ensure that we have a valid GPE number */ gpe_event_info =acpi_ev_get_gpe_event_info (gpe_device, gpe_number); -if (!gpe_event_info) { +if (gpe_event_info) { + gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; + }else { status =AE_BAD_PARAMETER ; - goto unlock_and_exit; - } - -if (gpe_event_info->flags &ACPI_GPE_CAN_WAKE ) { - goto unlock_and_exit; } - gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; -if (gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) { - (void )acpi_raw_disable_gpe (gpe_event_info); - } - -unlock_and_exit:acpi_os_release_lock (acpi_gbl_gpe_lock, flags);return_ACPI_STATUS (status); }
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_dstruct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK;union acpi_operand_object *obj_desc;struct acpi_namespace_node *node;struct acpi_gpe_block_info *gpe_block;
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_d obj_desc->device.gpe_block = gpe_block; -/* Enable the runtime GPEs in the new block */ - - status =acpi_ev_initialize_gpe_block (node, gpe_block); - unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );return_ACPI_STATUS (status);
@@ -924,3 +911,37 @@ acpi_status acpi_enable_all_runtime_gpesreturn_ACPI_STATUS (status); } + +/****************************************************************************** +* +* FUNCTION: acpi_complete_gpe_initialization +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and +* are not pointed to by any device _PRW methods indicating that +* these GPEs are generally intended for system or device wakeup +* (such GPEs have to be enabled directly when the devices whose +* _PRW methods point to them are set up for wakeup signaling). +* +******************************************************************************/ + +acpi_status acpi_complete_gpe_initialization (void ) +{ +acpi_status status; + +ACPI_FUNCTION_TRACE (acpi_complete_gpe_initialization); + + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS ); +if (ACPI_FAILURE (status)) { +return_ACPI_STATUS (status); + } + + status =acpi_ev_walk_gpe_list (acpi_ev_initialize_gpe_block,NULL ); + + (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); + +return_ACPI_STATUS (status); +}
drivers/acpi/acpica/acevents.h +3 -2
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_nam struct acpi_gpe_block_info **return_gpe_block);acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block); +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored);acpi_status acpi_ev_delete_gpe_block (struct acpi_gpe_block_info *gpe_block);
drivers/acpi/acpica/evgpeblk.c +11 -23
@@ -389,7 +389,6 @@ acpi_ev_create_gpe_block(struct acpi_nam walk_info.gpe_block = gpe_block; walk_info.gpe_device = gpe_device; - walk_info.enable_this_gpe = FALSE; walk_info.execute_by_owner_id = FALSE; status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
@@ -434,14 +433,14 @@ acpi_ev_create_gpe_block(struct acpi_nam******************************************************************************/ acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block) +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored) {acpi_status status;struct acpi_gpe_event_info *gpe_event_info;u32 gpe_enabled_count;u32 gpe_index; -u32 gpe_number;u32 i;u32 j;
@@ -454,15 +453,12 @@ acpi_ev_initialize_gpe_block(struct acpi }/* -* Enable all GPEs that have a corresponding method. Any other GPEs -* within this block must be enabled via the acpi_enable_gpe interface. +* Enable all GPEs that have a corresponding method and have the +* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must +* be enabled via the acpi_enable_gpe() interface. */ gpe_enabled_count =0 ; -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } -for (i =0 ; i < gpe_block->register_count; i++) {for (j =0 ; j <ACPI_GPE_REGISTER_WIDTH ; j++) {
@@ -470,27 +466,19 @@ acpi_ev_initialize_gpe_block(struct acpi gpe_index = (i *ACPI_GPE_REGISTER_WIDTH ) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; - gpe_number = gpe_index + gpe_block->block_base_number;/* Ignore GPEs that have no corresponding _Lxx/_Exx method */ -if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD )) { +if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) + || (gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) {continue ; } -/* -* If the GPE has already been enabled for runtime -* signaling, make sure it remains enabled, but do not -* increment its reference counter. -*/ - status = gpe_event_info->runtime_count ? -acpi_ev_enable_gpe (gpe_event_info) : -acpi_enable_gpe (gpe_device, gpe_number); - + status =acpi_raw_enable_gpe (gpe_event_info);if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); +"Could not enable GPE 0x%02X" , + gpe_index + gpe_block->block_base_number));continue ; }
include/acpi/acpixf.h +2 -0
@@ -308,6 +308,8 @@ acpi_install_gpe_block(acpi_handle gpe_dacpi_status acpi_remove_gpe_block (acpi_handle gpe_device); +acpi_status acpi_complete_gpe_initialization (void ); +/* * Resource interfaces */
drivers/acpi/acpica/aclocal.h +1 -1
@@ -413,6 +413,7 @@ struct acpi_handler_info {void *context;/* Context to be passed to handler */ struct acpi_namespace_node *method_node;/* Method node for this GPE level (saved) */ u8 orig_flags;/* Original misc info about this GPE */ +u8 orig_enabled;/* Set if the GPE was originally enabled */ };union acpi_gpe_dispatch_info {
@@ -473,7 +474,6 @@ struct acpi_gpe_walk_info {struct acpi_gpe_block_info *gpe_block;u16 count;acpi_owner_id owner_id; -u8 enable_this_gpe;u8 execute_by_owner_id; };
drivers/acpi/acpica/evgpeinit.c +0 -28
@@ -239,7 +239,6 @@ void acpi_ev_update_gpes(acpi_owner_id t walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count =0 ; - walk_info.enable_this_gpe = TRUE;/* Walk the interrupt level descriptor list */
@@ -301,8 +300,6 @@ void acpi_ev_update_gpes(acpi_owner_id t* * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods * with that owner. -* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE -* method is immediately enabled (Used for Load/load_table operators) * ******************************************************************************/
@@ -315,8 +312,6 @@ acpi_ev_match_gpe_method(acpi_handle objstruct acpi_gpe_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);struct acpi_gpe_event_info *gpe_event_info; -struct acpi_namespace_node *gpe_device; -acpi_status status;u32 gpe_number;char name[ACPI_NAME_SIZE +1 ];u8 type;
@@ -421,29 +416,6 @@ acpi_ev_match_gpe_method(acpi_handle obj gpe_event_info->flags |= (u8)(type |ACPI_GPE_DISPATCH_METHOD ); gpe_event_info->dispatch.method_node = method_node; -/* -* Enable this GPE if requested. This only happens when during the -* execution of a Load or load_table operator. We have found a new -* GPE method and want to immediately enable the GPE if it is a -* runtime GPE. -*/ -if (walk_info->enable_this_gpe) { - - walk_info->count++; - gpe_device = walk_info->gpe_device; - -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } - - status =acpi_enable_gpe (gpe_device, gpe_number); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); - } - } -ACPI_DEBUG_PRINT ((ACPI_DB_LOAD ,"Registered GPE method %s as GPE number 0x%.2X\n" , name, gpe_number));
drivers/acpi/acpica/evevent.c +0 -41
47 lines not on this page · raw message
drivers/acpi/acpica/utxface.c +0 -13
@@ -290,19 +290,6 @@ acpi_status acpi_initialize_objects(u32 }/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* NOTE: Currently, there seems to be no need to run the _REG methods -* before enabling the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) -return (status); - } - -/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
drivers/acpi/bus.c +1 -0
@@ -1032,6 +1032,7 @@ static int __init acpi_init(void)dmi_check_system (power_nocheck_dmi_table);acpi_scan_init (); +acpi_complete_gpe_initialization ();acpi_ec_init ();acpi_power_init ();acpi_sysfs_init ();
drivers/acpi/acpica/evxface.c +10 -9
@@ -793,15 +793,16 @@ acpi_install_gpe_handler(acpi_handle gpe (ACPI_GPE_XRUPT_TYPE_MASK |ACPI_GPE_DISPATCH_MASK );/* -* If the GPE is associated with a method and it cannot wake up the -* system from sleep states, it was enabled automatically during -* initialization, so it has to be disabled now to avoid spurious -* execution of the handler. +* If the GPE is associated with a method, it might have been enabled +* automatically during initialization, in which case it has to be +* disabled now to avoid spurious execution of the handler. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && gpe_event_info->runtime_count) { + handler->orig_enabled =1 ; (void )acpi_raw_disable_gpe (gpe_event_info); + }/* Install the handler */
@@ -904,13 +905,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_ gpe_event_info->flags |= handler->orig_flags;/* -* If the GPE was previously associated with a method and it cannot wake -* up the system from sleep states, it should be enabled at this point -* to restore the post-initialization configuration. +* If the GPE was previously associated with a method and it was +* enabled, it should be enabled at this point to restore the +* post-initialization configuration. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && handler->orig_enabled) (void )acpi_raw_enable_gpe (gpe_event_info);/* Now we can free the handler object */
Quoted 6 lines · Rafael J. Wysocki
Bob, Matthew,
The patch below implements the idea we've been recently discussing off-list, to only enable "runtime" GPEs after the ACPI namespace have been scanned and we know what GPEs are pointed to by
_PRWmethods.
Quoted 8 lines
It is on top of the current mainline Linux kernel (2.6.36-rc2+) which contains my patches that removed the
_PRWscan from the ACPICA code and modified the GPE handler installation/removal.Fortunately, the patch turns out to be rather straightforward, although I have one reservation. Namely, I'm not sure if any GPEs can be added after
acpi_scan_init()has returned, in which case we may want to enable them as soon as they are found and some code to do that will be necessary.
Isn't it possible (at least in theory) to hot-add an ACPI0006 GPE Block Device after acpi_scan_init()?
Quoted 10 lines
---
From: Rafael J. Wysocki <[email protected]>
Subject: ACPI / ACPICA: Defer enabling of runtime GPEsThe current ACPI GPEs initialization code has a problem that it enables some GPEs pointed to by device
_PRWmethods and are 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 ofacpi_gpe_can_wake(), but it would be better no to enable them at all until really necessary.
Typo: ^ I think you meant "not"
drivers/acpi/acpica/evxfevnt.c acpi_status acpi_gpe_can_wake(acpi_handl
Quoted 23 lines
Modify the initialization of GPEs so that the ones that have associated
_Lxxor_Exxmethods and are not pointed to by any_PRWmethods will be enabled after the namespace scan is complete.Signed-off-by Rafael J. Wysocki <[email protected]>--- drivers/acpi/acpica/acevents.h | 5 ++- drivers/acpi/acpica/aclocal.h | 2 - drivers/acpi/acpica/evevent.c | 41 ----------------------------- drivers/acpi/acpica/evgpeblk.c | 34 ++++++++---------------- drivers/acpi/acpica/evgpeinit.c | 28 -------------------- drivers/acpi/acpica/evxface.c | 19 +++++++------ drivers/acpi/acpica/evxfevnt.c | 55 +++++++++++++++++++++++++++------------- drivers/acpi/acpica/utxface.c | 13 --------- drivers/acpi/bus.c | 1 include/acpi/acpixf.h | 2 + 10 files changed, 66 insertions(+), 134 deletions(-)Index:
linux-2.6/drivers/acpi/acpica/evxfevnt.c
===================================================================drivers/acpi/acpica/evxfevnt.c +0
-0@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handl
I suspect the function comment no longer matches the code.
Quoted 410 lines
drivers/acpi/acpica/evxfevnt.c +38
-17/* Ensure that we have a valid GPE number */ gpe_event_info =acpi_ev_get_gpe_event_info (gpe_device, gpe_number); -if (!gpe_event_info) { +if (gpe_event_info) { + gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; + }else { status =AE_BAD_PARAMETER ; - goto unlock_and_exit; - } - -if (gpe_event_info->flags &ACPI_GPE_CAN_WAKE ) { - goto unlock_and_exit; } - gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; -if (gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) { - (void )acpi_raw_disable_gpe (gpe_event_info); - } - -unlock_and_exit:acpi_os_release_lock (acpi_gbl_gpe_lock, flags);return_ACPI_STATUS (status); }@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_dstruct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK;union acpi_operand_object *obj_desc;struct acpi_namespace_node *node;struct acpi_gpe_block_info *gpe_block;@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_d obj_desc->device.gpe_block = gpe_block; -/* Enable the runtime GPEs in the new block */ - - status =acpi_ev_initialize_gpe_block (node, gpe_block); - unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );return_ACPI_STATUS (status);@@ -924,3 +911,37 @@ acpi_status acpi_enable_all_runtime_gpesreturn_ACPI_STATUS (status); } + +/****************************************************************************** +* +* FUNCTION: acpi_complete_gpe_initialization +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and +* are not pointed to by any device _PRW methods indicating that +* these GPEs are generally intended for system or device wakeup +* (such GPEs have to be enabled directly when the devices whose +* _PRW methods point to them are set up for wakeup signaling). +* +******************************************************************************/ + +acpi_status acpi_complete_gpe_initialization (void ) +{ +acpi_status status; + +ACPI_FUNCTION_TRACE (acpi_complete_gpe_initialization); + + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS ); +if (ACPI_FAILURE (status)) { +return_ACPI_STATUS (status); + } + + status =acpi_ev_walk_gpe_list (acpi_ev_initialize_gpe_block,NULL ); + + (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); + +return_ACPI_STATUS (status); +}Index:
linux-2.6/drivers/acpi/acpica/acevents.h
===================================================================drivers/acpi/acpica/acevents.h +3
-2@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_nam struct acpi_gpe_block_info **return_gpe_block);acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block); +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored);acpi_status acpi_ev_delete_gpe_block (struct acpi_gpe_block_info *gpe_block);Index:
linux-2.6/drivers/acpi/acpica/evgpeblk.c
===================================================================drivers/acpi/acpica/evgpeblk.c +11
-23@@ -389,7 +389,6 @@ acpi_ev_create_gpe_block(struct acpi_nam walk_info.gpe_block = gpe_block; walk_info.gpe_device = gpe_device; - walk_info.enable_this_gpe = FALSE; walk_info.execute_by_owner_id = FALSE; status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,@@ -434,14 +433,14 @@ acpi_ev_create_gpe_block(struct acpi_nam******************************************************************************/ acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block) +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored) {acpi_status status;struct acpi_gpe_event_info *gpe_event_info;u32 gpe_enabled_count;u32 gpe_index; -u32 gpe_number;u32 i;u32 j;@@ -454,15 +453,12 @@ acpi_ev_initialize_gpe_block(struct acpi }/* -* Enable all GPEs that have a corresponding method. Any other GPEs -* within this block must be enabled via the acpi_enable_gpe interface. +* Enable all GPEs that have a corresponding method and have the +* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must +* be enabled via the acpi_enable_gpe() interface. */ gpe_enabled_count =0 ; -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } -for (i =0 ; i < gpe_block->register_count; i++) {for (j =0 ; j <ACPI_GPE_REGISTER_WIDTH ; j++) {@@ -470,27 +466,19 @@ acpi_ev_initialize_gpe_block(struct acpi gpe_index = (i *ACPI_GPE_REGISTER_WIDTH ) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; - gpe_number = gpe_index + gpe_block->block_base_number;/* Ignore GPEs that have no corresponding _Lxx/_Exx method */ -if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD )) { +if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) + || (gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) {continue ; } -/* -* If the GPE has already been enabled for runtime -* signaling, make sure it remains enabled, but do not -* increment its reference counter. -*/ - status = gpe_event_info->runtime_count ? -acpi_ev_enable_gpe (gpe_event_info) : -acpi_enable_gpe (gpe_device, gpe_number); - + status =acpi_raw_enable_gpe (gpe_event_info);if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); +"Could not enable GPE 0x%02X" , + gpe_index + gpe_block->block_base_number));continue ; }Index:
linux-2.6/include/acpi/acpixf.h
===================================================================include/acpi/acpixf.h +2
-0@@ -308,6 +308,8 @@ acpi_install_gpe_block(acpi_handle gpe_dacpi_status acpi_remove_gpe_block (acpi_handle gpe_device); +acpi_status acpi_complete_gpe_initialization (void ); +/* * Resource interfaces */ Index:
linux-2.6/drivers/acpi/acpica/aclocal.h
===================================================================drivers/acpi/acpica/aclocal.h +1
-1@@ -413,6 +413,7 @@ struct acpi_handler_info {void *context;/* Context to be passed to handler */ struct acpi_namespace_node *method_node;/* Method node for this GPE level (saved) */ u8 orig_flags;/* Original misc info about this GPE */ +u8 orig_enabled;/* Set if the GPE was originally enabled */ };union acpi_gpe_dispatch_info {@@ -473,7 +474,6 @@ struct acpi_gpe_walk_info {struct acpi_gpe_block_info *gpe_block;u16 count;acpi_owner_id owner_id; -u8 enable_this_gpe;u8 execute_by_owner_id; };Index:
linux-2.6/drivers/acpi/acpica/evgpeinit.c
===================================================================drivers/acpi/acpica/evgpeinit.c +0
-28@@ -239,7 +239,6 @@ void acpi_ev_update_gpes(acpi_owner_id t walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count =0 ; - walk_info.enable_this_gpe = TRUE;/* Walk the interrupt level descriptor list */ @@ -301,8 +300,6 @@ void acpi_ev_update_gpes(acpi_owner_id t* * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods * with that owner. -* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE -* method is immediately enabled (Used for Load/load_table operators) * ******************************************************************************/ @@ -315,8 +312,6 @@ acpi_ev_match_gpe_method(acpi_handle objstruct acpi_gpe_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);struct acpi_gpe_event_info *gpe_event_info; -struct acpi_namespace_node *gpe_device; -acpi_status status;u32 gpe_number;char name[ACPI_NAME_SIZE +1 ];u8 type;@@ -421,29 +416,6 @@ acpi_ev_match_gpe_method(acpi_handle obj gpe_event_info->flags |= (u8)(type |ACPI_GPE_DISPATCH_METHOD ); gpe_event_info->dispatch.method_node = method_node; -/* -* Enable this GPE if requested. This only happens when during the -* execution of a Load or load_table operator. We have found a new -* GPE method and want to immediately enable the GPE if it is a -* runtime GPE. -*/ -if (walk_info->enable_this_gpe) { - - walk_info->count++; - gpe_device = walk_info->gpe_device; - -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } - - status =acpi_enable_gpe (gpe_device, gpe_number); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); - } - } -ACPI_DEBUG_PRINT ((ACPI_DB_LOAD ,"Registered GPE method %s as GPE number 0x%.2X\n" , name, gpe_number));Index:
linux-2.6/drivers/acpi/acpica/evevent.c
===================================================================drivers/acpi/acpica/evevent.c +0
-41@@ -95,47 +95,6 @@ acpi_status acpi_ev_initialize_events(vo/******************************************************************************* * -* FUNCTION: acpi_ev_install_fadt_gpes -* -* PARAMETERS: None -* -* RETURN: Status -* -* DESCRIPTION: Completes initialization of the FADT-defined GPE blocks -* (0 and 1). The HW must be fully initialized at this point, -* including global lock support. -* -******************************************************************************/ - -acpi_status acpi_ev_install_fadt_gpes (void ) -{ -acpi_status status; - -ACPI_FUNCTION_TRACE (ev_install_fadt_gpes); - -/* Namespace must be locked */ - - status =acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE ); -if (ACPI_FAILURE (status)) { -return (status); - } - -/* FADT GPE Block 0 */ - - (void )acpi_ev_initialize_gpe_block (acpi_gbl_fadt_gpe_device, - acpi_gbl_gpe_fadt_blocks[0 ]); - -/* FADT GPE Block 1 */ - - (void )acpi_ev_initialize_gpe_block (acpi_gbl_fadt_gpe_device, - acpi_gbl_gpe_fadt_blocks[1 ]); - - (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE ); -return_ACPI_STATUS (AE_OK ); -} - -/******************************************************************************* -* * FUNCTION: acpi_ev_install_xrupt_handlers * * PARAMETERS: None Index:
linux-2.6/drivers/acpi/acpica/utxface.c
===================================================================drivers/acpi/acpica/utxface.c +0
-13@@ -290,19 +290,6 @@ acpi_status acpi_initialize_objects(u32 }/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* NOTE: Currently, there seems to be no need to run the _REG methods -* before enabling the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) -return (status); - } - -/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory. Index:
linux-2.6/drivers/acpi/bus.c
===================================================================drivers/acpi/bus.c +1
-0@@ -1032,6 +1032,7 @@ static int __init acpi_init(void)dmi_check_system (power_nocheck_dmi_table);acpi_scan_init (); +acpi_complete_gpe_initialization ();acpi_ec_init ();acpi_power_init ();acpi_sysfs_init ();Index:
linux-2.6/drivers/acpi/acpica/evxface.c
===================================================================drivers/acpi/acpica/evxface.c +10
-10@@ -793,15 +793,16 @@ acpi_install_gpe_handler(acpi_handle gpe (ACPI_GPE_XRUPT_TYPE_MASK |ACPI_GPE_DISPATCH_MASK );/* -* If the GPE is associated with a method and it cannot wake up the -* system from sleep states, it was enabled automatically during -* initialization, so it has to be disabled now to avoid spurious -* execution of the handler. +* If the GPE is associated with a method, it might have been enabled +* automatically during initialization, in which case it has to be +* disabled now to avoid spurious execution of the handler. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && gpe_event_info->runtime_count) { + handler->orig_enabled =1 ; (void )acpi_raw_disable_gpe (gpe_event_info); + }/* Install the handler */ @@ -904,13 +905,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_ gpe_event_info->flags |= handler->orig_flags;/* -* If the GPE was previously associated with a method and it cannot wake -* up the system from sleep states, it should be enabled at this point -* to restore the post-initialization configuration. +* If the GPE was previously associated with a method and it was +* enabled, it should be enabled at this point to restore the +* post-initialization configuration. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && handler->orig_enabled) (void )acpi_raw_enable_gpe (gpe_event_info);/* Now we can free the handler object */ --To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/1 ACPI / ACPICA: Defer enabling of runtime GPEs (v2)
Quoted 11 lines · Bjorn Helgaas
Quoted 10 lines · Rafael J. Wysocki
Bob, Matthew,
The patch below implements the idea we've been recently discussing off-list, to only enable "runtime" GPEs after the ACPI namespace have been scanned and we know what GPEs are pointed to by
_PRWmethods.It is on top of the current mainline Linux kernel (2.6.36-rc2+) which contains my patches that removed the
_PRWscan from the ACPICA code and modified the GPE handler installation/removal.
Quoted 7 lines
Quoted 4 lines
Fortunately, the patch turns out to be rather straightforward, although I have one reservation. Namely, I'm not sure if any GPEs can be added after
acpi_scan_init()has returned, in which case we may want to enable them as soon as they are found and some code to do that will be necessary.Isn't it possible (at least in theory) to hot-add an ACPI0006 GPE Block Device after
acpi_scan_init()?
Yes, in theory it is possible, but I'm not sure we handle that at all.
Just in case, though, I reworked the patch so that the "hot-added" GPEs are automatically enabled if they are added after the initial namespace scan. The new version is appended.
Quoted 4 lines
Quoted 4 lines
---
From: Rafael J. Wysocki <[email protected]>
Subject: ACPI / ACPICA: Defer enabling of runtime GPEs
Quoted 8 lines
Quoted 6 lines
The current ACPI GPEs initialization code has a problem that it enables some GPEs pointed to by device
_PRWmethods and are 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 ofacpi_gpe_can_wake(), but it would be better no to enable them at all until really necessary.Typo: ^ I think you meant "not"
That's correct, thanks. It's fixed in the changelog below.
Quoted 5 lines
Quoted 5 lines
Modify the initialization of GPEs so that the ones that have associated
_Lxxor_Exxmethods and are not pointed to by any_PRWmethods will be enabled after the namespace scan is complete.Signed-off-by Rafael J. Wysocki <[email protected]>
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: ACPI / ACPICA: Defer enabling of runtime GPEs (v2)
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.
--- drivers/acpi/acpica/acevents.h | 5 ++- drivers/acpi/acpica/acglobal.h | 1 drivers/acpi/acpica/aclocal.h | 1 drivers/acpi/acpica/evevent.c | 41 ----------------------------- drivers/acpi/acpica/evgpeblk.c | 33 +++++++---------------- drivers/acpi/acpica/evgpeinit.c | 2 - drivers/acpi/acpica/evxface.c | 19 +++++++------ drivers/acpi/acpica/evxfevnt.c | 56 +++++++++++++++++++++++++++------------- drivers/acpi/acpica/utglobal.c | 1 drivers/acpi/acpica/utxface.c | 13 --------- drivers/acpi/bus.c | 1 include/acpi/acpixf.h | 2 + 12 files changed, 70 insertions(+), 105 deletions(-)
drivers/acpi/acpica/evxfevnt.c +39 -17
@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handl/* Ensure that we have a valid GPE number */ gpe_event_info =acpi_ev_get_gpe_event_info (gpe_device, gpe_number); -if (!gpe_event_info) { +if (gpe_event_info) { + gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; + }else { status =AE_BAD_PARAMETER ; - goto unlock_and_exit; - } - -if (gpe_event_info->flags &ACPI_GPE_CAN_WAKE ) { - goto unlock_and_exit; } - gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; -if (gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) { - (void )acpi_raw_disable_gpe (gpe_event_info); - } - -unlock_and_exit:acpi_os_release_lock (acpi_gbl_gpe_lock, flags);return_ACPI_STATUS (status); }
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_dstruct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK;union acpi_operand_object *obj_desc;struct acpi_namespace_node *node;struct acpi_gpe_block_info *gpe_block;
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_d obj_desc->device.gpe_block = gpe_block; -/* Enable the runtime GPEs in the new block */ - - status =acpi_ev_initialize_gpe_block (node, gpe_block); - unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );return_ACPI_STATUS (status);
@@ -924,3 +911,38 @@ acpi_status acpi_enable_all_runtime_gpesreturn_ACPI_STATUS (status); } + +/****************************************************************************** +* +* FUNCTION: acpi_start_gpes +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and +* are not pointed to by any device _PRW methods indicating that +* these GPEs are generally intended for system or device wakeup +* (such GPEs have to be enabled directly when the devices whose +* _PRW methods point to them are set up for wakeup signaling). +* +******************************************************************************/ + +acpi_status acpi_start_gpes (void ) +{ +acpi_status status; + +ACPI_FUNCTION_TRACE (acpi_start_gpes); + + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS ); +if (ACPI_FAILURE (status)) { +return_ACPI_STATUS (status); + } + + acpi_auto_enable_gpes = TRUE; + status =acpi_ev_walk_gpe_list (acpi_ev_initialize_gpe_block,NULL ); + + (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); + +return_ACPI_STATUS (status); +}
drivers/acpi/acpica/acevents.h +3 -2
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_nam struct acpi_gpe_block_info **return_gpe_block);acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block); +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored);acpi_status acpi_ev_delete_gpe_block (struct acpi_gpe_block_info *gpe_block);
drivers/acpi/acpica/evgpeblk.c +11 -22
@@ -434,14 +434,14 @@ acpi_ev_create_gpe_block(struct acpi_nam******************************************************************************/ acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block) +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored) {acpi_status status;struct acpi_gpe_event_info *gpe_event_info;u32 gpe_enabled_count;u32 gpe_index; -u32 gpe_number;u32 i;u32 j;
@@ -454,15 +454,12 @@ acpi_ev_initialize_gpe_block(struct acpi }/* -* Enable all GPEs that have a corresponding method. Any other GPEs -* within this block must be enabled via the acpi_enable_gpe interface. +* Enable all GPEs that have a corresponding method and have the +* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must +* be enabled via the acpi_enable_gpe() interface. */ gpe_enabled_count =0 ; -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } -for (i =0 ; i < gpe_block->register_count; i++) {for (j =0 ; j <ACPI_GPE_REGISTER_WIDTH ; j++) {
@@ -470,27 +467,19 @@ acpi_ev_initialize_gpe_block(struct acpi gpe_index = (i *ACPI_GPE_REGISTER_WIDTH ) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; - gpe_number = gpe_index + gpe_block->block_base_number;/* Ignore GPEs that have no corresponding _Lxx/_Exx method */ -if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD )) { +if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) + || (gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) {continue ; } -/* -* If the GPE has already been enabled for runtime -* signaling, make sure it remains enabled, but do not -* increment its reference counter. -*/ - status = gpe_event_info->runtime_count ? -acpi_ev_enable_gpe (gpe_event_info) : -acpi_enable_gpe (gpe_device, gpe_number); - + status =acpi_raw_enable_gpe (gpe_event_info);if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); +"Could not enable GPE 0x%02X" , + gpe_index + gpe_block->block_base_number));continue ; }
include/acpi/acpixf.h +2 -0
@@ -308,6 +308,8 @@ acpi_install_gpe_block(acpi_handle gpe_dacpi_status acpi_remove_gpe_block (acpi_handle gpe_device); +acpi_status acpi_start_gpes (void ); +/* * Resource interfaces */
drivers/acpi/acpica/aclocal.h +1 -0
@@ -413,6 +413,7 @@ struct acpi_handler_info {void *context;/* Context to be passed to handler */ struct acpi_namespace_node *method_node;/* Method node for this GPE level (saved) */ u8 orig_flags;/* Original misc info about this GPE */ +u8 orig_enabled;/* Set if the GPE was originally enabled */ };union acpi_gpe_dispatch_info {
drivers/acpi/acpica/evevent.c +0 -41
47 lines not on this page · raw message
drivers/acpi/acpica/utxface.c +0 -13
@@ -290,19 +290,6 @@ acpi_status acpi_initialize_objects(u32 }/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* NOTE: Currently, there seems to be no need to run the _REG methods -* before enabling the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) -return (status); - } - -/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
drivers/acpi/bus.c +1 -0
@@ -1032,6 +1032,7 @@ static int __init acpi_init(void)dmi_check_system (power_nocheck_dmi_table);acpi_scan_init (); +acpi_start_gpes ();acpi_ec_init ();acpi_power_init ();acpi_sysfs_init ();
drivers/acpi/acpica/evxface.c +10 -9
@@ -793,15 +793,16 @@ acpi_install_gpe_handler(acpi_handle gpe (ACPI_GPE_XRUPT_TYPE_MASK |ACPI_GPE_DISPATCH_MASK );/* -* If the GPE is associated with a method and it cannot wake up the -* system from sleep states, it was enabled automatically during -* initialization, so it has to be disabled now to avoid spurious -* execution of the handler. +* If the GPE is associated with a method, it might have been enabled +* automatically during initialization, in which case it has to be +* disabled now to avoid spurious execution of the handler. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && gpe_event_info->runtime_count) { + handler->orig_enabled =1 ; (void )acpi_raw_disable_gpe (gpe_event_info); + }/* Install the handler */
@@ -904,13 +905,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_ gpe_event_info->flags |= handler->orig_flags;/* -* If the GPE was previously associated with a method and it cannot wake -* up the system from sleep states, it should be enabled at this point -* to restore the post-initialization configuration. +* If the GPE was previously associated with a method and it was +* enabled, it should be enabled at this point to restore the +* post-initialization configuration. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && handler->orig_enabled) (void )acpi_raw_enable_gpe (gpe_event_info);/* Now we can free the handler object */
drivers/acpi/acpica/acglobal.h +1 -0
@@ -364,6 +364,7 @@ ACPI_EXTERN struct acpi_fixed_event_hand ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS ]; +ACPI_EXTERN u8 acpi_auto_enable_gpes;/***************************************************************************** *
drivers/acpi/acpica/utglobal.c +1 -0
@@ -766,6 +766,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_gpe_fadt_blocks[0 ] =NULL ; acpi_gbl_gpe_fadt_blocks[1 ] =NULL ; acpi_current_gpe_count =0 ; + acpi_auto_enable_gpes = FALSE;/* Global handlers */
drivers/acpi/acpica/evgpeinit.c +1 -1
@@ -239,7 +239,7 @@ void acpi_ev_update_gpes(acpi_owner_id t walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count =0 ; - walk_info.enable_this_gpe = TRUE; + walk_info.enable_this_gpe = acpi_auto_enable_gpes;/* Walk the interrupt level descriptor list */
PATCH 1/1 ACPI / ACPICA: Defer enabling of runtime GPEs (v2)
Quoted 17 lines · Rafael J. Wysocki
Quoted 16 lines · Bjorn Helgaas
Quoted 14 lines · Rafael J. Wysocki
Bob, Matthew,
The patch below implements the idea we've been recently discussing off-list, to only enable "runtime" GPEs after the ACPI namespace have been scanned and we know what GPEs are pointed to by
_PRWmethods.It is on top of the current mainline Linux kernel (2.6.36-rc2+) which contains my patches that removed the
_PRWscan from the ACPICA code and modified the GPE handler installation/removal.Fortunately, the patch turns out to be rather straightforward, although I have one reservation. Namely, I'm not sure if any GPEs can be added after
acpi_scan_init()has returned, in which case we may want to enable them as soon as they are found and some code to do that will be necessary.
Quoted 8 lines
Quoted 2 lines
Isn't it possible (at least in theory) to hot-add an ACPI0006 GPE Block Device after
acpi_scan_init()?Yes, in theory it is possible, but I'm not sure we handle that at all.
Just in case, though, I reworked the patch so that the "hot-added" GPEs are automatically enabled if they are added after the initial namespace scan. The new version is appended.
Well, this one still has the problem that the "hot-added" GPEs are enabled even if they are pointed to by _PRW (presumably from other "hot-added" devices). So, below is the third version of the patch that should take care of this issue.
In simplification, it works like this. When a new GPE block is added, acpi_ev_create_gpe_block() marks it as unitialized and clears acpi_all_gpes_initialized. Afterwards, when the newly added part of the namespace is scanned, the host OS is supposed to call acpi_update_gpes() that will notice there are some GPE blocks to initialize and will enable the GPEs with _Lxx or _Exx that are not pointed to by _PRW in that blocks. Finally, it will set acpi_all_gpes_initialized to avoid browsing the list of GPE blocks unnecessarily.
Thanks,
Rafael
---
From: Rafael J. Wysocki <[email protected]>
Subject: 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.
--- drivers/acpi/acpica/acevents.h | 5 +-- drivers/acpi/acpica/acglobal.h | 1 drivers/acpi/acpica/aclocal.h | 3 + drivers/acpi/acpica/evevent.c | 41 -------------------------- drivers/acpi/acpica/evgpeblk.c | 47 +++++++++++++----------------- drivers/acpi/acpica/evgpeinit.c | 31 -------------------- drivers/acpi/acpica/evxface.c | 19 ++++++------ drivers/acpi/acpica/evxfevnt.c | 61 ++++++++++++++++++++++++++++------------ drivers/acpi/acpica/utglobal.c | 1 drivers/acpi/acpica/utxface.c | 13 -------- drivers/acpi/dock.c | 1 drivers/acpi/scan.c | 10 +++++- include/acpi/acpixf.h | 2 + 13 files changed, 95 insertions(+), 140 deletions(-)
drivers/acpi/acpica/evxfevnt.c +44 -17
@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handl/* Ensure that we have a valid GPE number */ gpe_event_info =acpi_ev_get_gpe_event_info (gpe_device, gpe_number); -if (!gpe_event_info) { +if (gpe_event_info) { + gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; + }else { status =AE_BAD_PARAMETER ; - goto unlock_and_exit; - } - -if (gpe_event_info->flags &ACPI_GPE_CAN_WAKE ) { - goto unlock_and_exit; } - gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; -if (gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) { - (void )acpi_raw_disable_gpe (gpe_event_info); - } - -unlock_and_exit:acpi_os_release_lock (acpi_gbl_gpe_lock, flags);return_ACPI_STATUS (status); }
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_dstruct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK;union acpi_operand_object *obj_desc;struct acpi_namespace_node *node;struct acpi_gpe_block_info *gpe_block;
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_d obj_desc->device.gpe_block = gpe_block; -/* Enable the runtime GPEs in the new block */ - - status =acpi_ev_initialize_gpe_block (node, gpe_block); - unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );return_ACPI_STATUS (status);
@@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpesreturn_ACPI_STATUS (status); } + +/****************************************************************************** +* +* FUNCTION: acpi_update_gpes +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and +* are not pointed to by any device _PRW methods indicating that +* these GPEs are generally intended for system or device wakeup +* (such GPEs have to be enabled directly when the devices whose +* _PRW methods point to them are set up for wakeup signaling). +* +******************************************************************************/ + +acpi_status acpi_update_gpes (void ) +{ +acpi_status status; + +ACPI_FUNCTION_TRACE (acpi_update_gpes); + + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS ); +if (ACPI_FAILURE (status)) { +return_ACPI_STATUS (status); + }else if (acpi_all_gpes_initialized) { + goto unlock; + } + + status =acpi_ev_walk_gpe_list (acpi_ev_initialize_gpe_block,NULL ); +if (ACPI_SUCCESS (status)) { + acpi_all_gpes_initialized = TRUE; + } + +unlock: + (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); + +return_ACPI_STATUS (status); +}
drivers/acpi/acpica/acevents.h +3 -2
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_nam struct acpi_gpe_block_info **return_gpe_block);acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block); +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored);acpi_status acpi_ev_delete_gpe_block (struct acpi_gpe_block_info *gpe_block);
drivers/acpi/acpica/evgpeblk.c +21 -26
105 lines not on this page · raw message
include/acpi/acpixf.h +2 -0
@@ -308,6 +308,8 @@ acpi_install_gpe_block(acpi_handle gpe_dacpi_status acpi_remove_gpe_block (acpi_handle gpe_device); +acpi_status acpi_update_gpes (void ); +/* * Resource interfaces */
drivers/acpi/acpica/aclocal.h +2 -1
@@ -413,6 +413,7 @@ struct acpi_handler_info {void *context;/* Context to be passed to handler */ struct acpi_namespace_node *method_node;/* Method node for this GPE level (saved) */ u8 orig_flags;/* Original misc info about this GPE */ +u8 orig_enabled;/* Set if the GPE was originally enabled */ };union acpi_gpe_dispatch_info {
@@ -457,6 +458,7 @@ struct acpi_gpe_block_info {u32 register_count;/* Number of register pairs in block */ u16 gpe_count;/* Number of individual GPEs in block */ u8 block_base_number;/* Base GPE number for this block */ +u8 initialized;/* If set, the GPE block has been initialized */ };/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
@@ -473,7 +475,6 @@ struct acpi_gpe_walk_info {struct acpi_gpe_block_info *gpe_block;u16 count;acpi_owner_id owner_id; -u8 enable_this_gpe;u8 execute_by_owner_id; };
drivers/acpi/acpica/evgpeinit.c +1 -30
@@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void)* * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * result of a Load() or load_table() operation. If new GPE -* methods have been installed, register the new methods and -* enable and runtime GPEs that are associated with them. +* methods have been installed, register the new methods. * ******************************************************************************/
@@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id t walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count =0 ; - walk_info.enable_this_gpe = TRUE;/* Walk the interrupt level descriptor list */
@@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id t* * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods * with that owner. -* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE -* method is immediately enabled (Used for Load/load_table operators) * ******************************************************************************/
@@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle objstruct acpi_gpe_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);struct acpi_gpe_event_info *gpe_event_info; -struct acpi_namespace_node *gpe_device; -acpi_status status;u32 gpe_number;char name[ACPI_NAME_SIZE +1 ];u8 type;
@@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj gpe_event_info->flags |= (u8)(type |ACPI_GPE_DISPATCH_METHOD ); gpe_event_info->dispatch.method_node = method_node; -/* -* Enable this GPE if requested. This only happens when during the -* execution of a Load or load_table operator. We have found a new -* GPE method and want to immediately enable the GPE if it is a -* runtime GPE. -*/ -if (walk_info->enable_this_gpe) { - - walk_info->count++; - gpe_device = walk_info->gpe_device; - -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } - - status =acpi_enable_gpe (gpe_device, gpe_number); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); - } - } -ACPI_DEBUG_PRINT ((ACPI_DB_LOAD ,"Registered GPE method %s as GPE number 0x%.2X\n" , name, gpe_number));
drivers/acpi/acpica/evevent.c +0 -41
47 lines not on this page · raw message
drivers/acpi/acpica/utxface.c +0 -13
@@ -290,19 +290,6 @@ acpi_status acpi_initialize_objects(u32 }/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* NOTE: Currently, there seems to be no need to run the _REG methods -* before enabling the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) -return (status); - } - -/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
drivers/acpi/acpica/evxface.c +10 -9
@@ -793,15 +793,16 @@ acpi_install_gpe_handler(acpi_handle gpe (ACPI_GPE_XRUPT_TYPE_MASK |ACPI_GPE_DISPATCH_MASK );/* -* If the GPE is associated with a method and it cannot wake up the -* system from sleep states, it was enabled automatically during -* initialization, so it has to be disabled now to avoid spurious -* execution of the handler. +* If the GPE is associated with a method, it might have been enabled +* automatically during initialization, in which case it has to be +* disabled now to avoid spurious execution of the handler. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && gpe_event_info->runtime_count) { + handler->orig_enabled =1 ; (void )acpi_raw_disable_gpe (gpe_event_info); + }/* Install the handler */
@@ -904,13 +905,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_ gpe_event_info->flags |= handler->orig_flags;/* -* If the GPE was previously associated with a method and it cannot wake -* up the system from sleep states, it should be enabled at this point -* to restore the post-initialization configuration. +* If the GPE was previously associated with a method and it was +* enabled, it should be enabled at this point to restore the +* post-initialization configuration. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && handler->orig_enabled) (void )acpi_raw_enable_gpe (gpe_event_info);/* Now we can free the handler object */
drivers/acpi/acpica/acglobal.h +1 -0
@@ -364,6 +364,7 @@ ACPI_EXTERN struct acpi_fixed_event_hand ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS ]; +ACPI_EXTERN u8 acpi_all_gpes_initialized;/***************************************************************************** *
drivers/acpi/acpica/utglobal.c +1 -0
@@ -766,6 +766,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_gpe_fadt_blocks[0 ] =NULL ; acpi_gbl_gpe_fadt_blocks[1 ] =NULL ; acpi_current_gpe_count =0 ; + acpi_all_gpes_initialized = FALSE;/* Global handlers */
drivers/acpi/scan.c +9 -1
@@ -1420,6 +1420,7 @@ acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type) { struct acpi_bus_ops ops; +int result;memset (&ops,0 ,sizeof (ops)); ops.acpi_op_add =1 ;
@@ -1431,6 +1432,7 @@ EXPORT_SYMBOL(acpi_bus_add);int acpi_bus_start (struct acpi_device *device) {struct acpi_bus_ops ops; +int result;if (!device)return -EINVAL ;
@@ -1438,7 +1440,11 @@ int acpi_bus_start(struct acpi_device *dmemset (&ops,0 ,sizeof (ops)); ops.acpi_op_start =1 ; -return acpi_bus_scan (device->handle, &ops,NULL ); + result =acpi_bus_scan (device->handle, &ops,NULL ); + +acpi_update_gpes (); + +return result; }EXPORT_SYMBOL (acpi_bus_start);
@@ -1552,6 +1558,8 @@ int __init acpi_scan_init(void)if (result)acpi_device_unregister (acpi_root,ACPI_BUS_REMOVAL_NORMAL ); +else +acpi_update_gpes ();return result; }
drivers/acpi/dock.c +1 -0
@@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handcomplete_dock (ds);dock_event (ds, event,DOCK_EVENT );dock_lock (ds,1 ); +acpi_update_gpes ();break ; }if (dock_present (ds) ||dock_in_progress (ds))
RE: [PATCH] ACPI / ACPICA: Defer enabling of runtime GPEs (v2)
Rafael,
The wake/runtime GPE issue has stirred up some interest with our BIOS team. I'm working on that right now, will begin to look at your changes soon.
Thanks,
Bob
Quoted 15 lines
-----Original Message-----
From: Rafael J. Wysocki [mailto:[email protected]]
Sent: Tuesday, August 31, 2010 1:36 PM
To: Moore, Robert
Cc: Bjorn Helgaas; Matthew Garrett; Brown, Len; Len Brown; Lin, Ming M; ACPI Devel Maling List
Subject: [PATCH] ACPI / ACPICA: Defer enabling of runtime GPEs (v2)Quoted 5 lines · Rafael J. Wysocki
Quoted 4 lines · Bjorn Helgaas
Quoted 3 lines · Rafael J. Wysocki
Bob, Matthew,
The patch below implements the idea we've been recently discussing
off-list,
PATCH 1/1 ACPI / ACPICA: Defer enabling of runtime GPEs (v3)
From: Rafael J. Wysocki <[email protected]>
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.
--- drivers/acpi/acpica/acevents.h | 5 +-- drivers/acpi/acpica/acglobal.h | 1 drivers/acpi/acpica/aclocal.h | 3 + drivers/acpi/acpica/evevent.c | 41 -------------------------- drivers/acpi/acpica/evgpeblk.c | 47 +++++++++++++----------------- drivers/acpi/acpica/evgpeinit.c | 31 -------------------- drivers/acpi/acpica/evxface.c | 19 ++++++------ drivers/acpi/acpica/evxfevnt.c | 61 ++++++++++++++++++++++++++++------------ drivers/acpi/acpica/utglobal.c | 1 drivers/acpi/acpica/utxface.c | 13 -------- drivers/acpi/dock.c | 1 drivers/acpi/scan.c | 9 +++++ include/acpi/acpixf.h | 2 + 13 files changed, 94 insertions(+), 140 deletions(-)
drivers/acpi/acpica/evxfevnt.c +44 -17
@@ -379,21 +379,12 @@ acpi_status acpi_gpe_can_wake(acpi_handl/* Ensure that we have a valid GPE number */ gpe_event_info =acpi_ev_get_gpe_event_info (gpe_device, gpe_number); -if (!gpe_event_info) { +if (gpe_event_info) { + gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; + }else { status =AE_BAD_PARAMETER ; - goto unlock_and_exit; - } - -if (gpe_event_info->flags &ACPI_GPE_CAN_WAKE ) { - goto unlock_and_exit; } - gpe_event_info->flags |=ACPI_GPE_CAN_WAKE ; -if (gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) { - (void )acpi_raw_disable_gpe (gpe_event_info); - } - -unlock_and_exit:acpi_os_release_lock (acpi_gbl_gpe_lock, flags);return_ACPI_STATUS (status); }
@@ -651,7 +642,7 @@ acpi_install_gpe_block(acpi_handle gpe_dstruct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status; + acpi_status status = AE_OK;union acpi_operand_object *obj_desc;struct acpi_namespace_node *node;struct acpi_gpe_block_info *gpe_block;
@@ -715,10 +706,6 @@ acpi_install_gpe_block(acpi_handle gpe_d obj_desc->device.gpe_block = gpe_block; -/* Enable the runtime GPEs in the new block */ - - status =acpi_ev_initialize_gpe_block (node, gpe_block); - unlock_and_exit: (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );return_ACPI_STATUS (status);
@@ -924,3 +911,43 @@ acpi_status acpi_enable_all_runtime_gpesreturn_ACPI_STATUS (status); } + +/****************************************************************************** +* +* FUNCTION: acpi_update_gpes +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and +* are not pointed to by any device _PRW methods indicating that +* these GPEs are generally intended for system or device wakeup +* (such GPEs have to be enabled directly when the devices whose +* _PRW methods point to them are set up for wakeup signaling). +* +******************************************************************************/ + +acpi_status acpi_update_gpes (void ) +{ +acpi_status status; + +ACPI_FUNCTION_TRACE (acpi_update_gpes); + + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS ); +if (ACPI_FAILURE (status)) { +return_ACPI_STATUS (status); + }else if (acpi_all_gpes_initialized) { + goto unlock; + } + + status =acpi_ev_walk_gpe_list (acpi_ev_initialize_gpe_block,NULL ); +if (ACPI_SUCCESS (status)) { + acpi_all_gpes_initialized = TRUE; + } + +unlock: + (void )acpi_ut_release_mutex (ACPI_MTX_EVENTS ); + +return_ACPI_STATUS (status); +}
drivers/acpi/acpica/acevents.h +3 -2
@@ -105,8 +105,9 @@ acpi_ev_create_gpe_block(struct acpi_nam struct acpi_gpe_block_info **return_gpe_block);acpi_status -acpi_ev_initialize_gpe_block (struct acpi_namespace_node *gpe_device, -struct acpi_gpe_block_info *gpe_block); +acpi_ev_initialize_gpe_block (struct acpi_gpe_xrupt_info *gpe_xrupt_info, +struct acpi_gpe_block_info *gpe_block, +void *ignored);acpi_status acpi_ev_delete_gpe_block (struct acpi_gpe_block_info *gpe_block);
drivers/acpi/acpica/evgpeblk.c +21 -26
105 lines not on this page · raw message
include/acpi/acpixf.h +2 -0
@@ -308,6 +308,8 @@ acpi_install_gpe_block(acpi_handle gpe_dacpi_status acpi_remove_gpe_block (acpi_handle gpe_device); +acpi_status acpi_update_gpes (void ); +/* * Resource interfaces */
drivers/acpi/acpica/aclocal.h +2 -1
@@ -413,6 +413,7 @@ struct acpi_handler_info {void *context;/* Context to be passed to handler */ struct acpi_namespace_node *method_node;/* Method node for this GPE level (saved) */ u8 orig_flags;/* Original misc info about this GPE */ +u8 orig_enabled;/* Set if the GPE was originally enabled */ };union acpi_gpe_dispatch_info {
@@ -457,6 +458,7 @@ struct acpi_gpe_block_info {u32 register_count;/* Number of register pairs in block */ u16 gpe_count;/* Number of individual GPEs in block */ u8 block_base_number;/* Base GPE number for this block */ +u8 initialized;/* If set, the GPE block has been initialized */ };/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
@@ -473,7 +475,6 @@ struct acpi_gpe_walk_info {struct acpi_gpe_block_info *gpe_block;u16 count;acpi_owner_id owner_id; -u8 enable_this_gpe;u8 execute_by_owner_id; };
drivers/acpi/acpica/evgpeinit.c +1 -30
@@ -210,8 +210,7 @@ acpi_status acpi_ev_gpe_initialize(void)* * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * result of a Load() or load_table() operation. If new GPE -* methods have been installed, register the new methods and -* enable and runtime GPEs that are associated with them. +* methods have been installed, register the new methods. * ******************************************************************************/
@@ -239,7 +238,6 @@ void acpi_ev_update_gpes(acpi_owner_id t walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count =0 ; - walk_info.enable_this_gpe = TRUE;/* Walk the interrupt level descriptor list */
@@ -301,8 +299,6 @@ void acpi_ev_update_gpes(acpi_owner_id t* * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods * with that owner. -* If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE -* method is immediately enabled (Used for Load/load_table operators) * ******************************************************************************/
@@ -315,8 +311,6 @@ acpi_ev_match_gpe_method(acpi_handle objstruct acpi_gpe_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);struct acpi_gpe_event_info *gpe_event_info; -struct acpi_namespace_node *gpe_device; -acpi_status status;u32 gpe_number;char name[ACPI_NAME_SIZE +1 ];u8 type;
@@ -421,29 +415,6 @@ acpi_ev_match_gpe_method(acpi_handle obj gpe_event_info->flags |= (u8)(type |ACPI_GPE_DISPATCH_METHOD ); gpe_event_info->dispatch.method_node = method_node; -/* -* Enable this GPE if requested. This only happens when during the -* execution of a Load or load_table operator. We have found a new -* GPE method and want to immediately enable the GPE if it is a -* runtime GPE. -*/ -if (walk_info->enable_this_gpe) { - - walk_info->count++; - gpe_device = walk_info->gpe_device; - -if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device =NULL ; - } - - status =acpi_enable_gpe (gpe_device, gpe_number); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status, -"Could not enable GPE 0x%02X" , - gpe_number)); - } - } -ACPI_DEBUG_PRINT ((ACPI_DB_LOAD ,"Registered GPE method %s as GPE number 0x%.2X\n" , name, gpe_number));
drivers/acpi/acpica/evevent.c +0 -41
47 lines not on this page · raw message
drivers/acpi/acpica/utxface.c +0 -13
@@ -290,19 +290,6 @@ acpi_status acpi_initialize_objects(u32 }/* -* Complete the GPE initialization for the GPE blocks defined in the FADT -* (GPE block 0 and 1). -* -* NOTE: Currently, there seems to be no need to run the _REG methods -* before enabling the GPEs. -*/ -if (!(flags &ACPI_NO_EVENT_INIT )) { - status =acpi_ev_install_fadt_gpes (); -if (ACPI_FAILURE (status)) -return (status); - } - -/* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory.
drivers/acpi/acpica/evxface.c +10 -9
@@ -793,15 +793,16 @@ acpi_install_gpe_handler(acpi_handle gpe (ACPI_GPE_XRUPT_TYPE_MASK |ACPI_GPE_DISPATCH_MASK );/* -* If the GPE is associated with a method and it cannot wake up the -* system from sleep states, it was enabled automatically during -* initialization, so it has to be disabled now to avoid spurious -* execution of the handler. +* If the GPE is associated with a method, it might have been enabled +* automatically during initialization, in which case it has to be +* disabled now to avoid spurious execution of the handler. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && gpe_event_info->runtime_count) { + handler->orig_enabled =1 ; (void )acpi_raw_disable_gpe (gpe_event_info); + }/* Install the handler */
@@ -904,13 +905,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_ gpe_event_info->flags |= handler->orig_flags;/* -* If the GPE was previously associated with a method and it cannot wake -* up the system from sleep states, it should be enabled at this point -* to restore the post-initialization configuration. +* If the GPE was previously associated with a method and it was +* enabled, it should be enabled at this point to restore the +* post-initialization configuration. */ if ((handler->orig_flags &ACPI_GPE_DISPATCH_METHOD ) - && !(gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) + && handler->orig_enabled) (void )acpi_raw_enable_gpe (gpe_event_info);/* Now we can free the handler object */
drivers/acpi/acpica/acglobal.h +1 -0
@@ -364,6 +364,7 @@ ACPI_EXTERN struct acpi_fixed_event_hand ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS ]; +ACPI_EXTERN u8 acpi_all_gpes_initialized;/***************************************************************************** *
drivers/acpi/acpica/utglobal.c +1 -0
@@ -766,6 +766,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_gpe_fadt_blocks[0 ] =NULL ; acpi_gbl_gpe_fadt_blocks[1 ] =NULL ; acpi_current_gpe_count =0 ; + acpi_all_gpes_initialized = FALSE;/* Global handlers */
drivers/acpi/scan.c +8 -1
@@ -1431,6 +1431,7 @@ EXPORT_SYMBOL(acpi_bus_add);int acpi_bus_start (struct acpi_device *device) {struct acpi_bus_ops ops; +int result;if (!device)return -EINVAL ;
@@ -1438,7 +1439,11 @@ int acpi_bus_start(struct acpi_device *dmemset (&ops,0 ,sizeof (ops)); ops.acpi_op_start =1 ; -return acpi_bus_scan (device->handle, &ops,NULL ); + result =acpi_bus_scan (device->handle, &ops,NULL ); + +acpi_update_gpes (); + +return result; }EXPORT_SYMBOL (acpi_bus_start);
@@ -1552,6 +1557,8 @@ int __init acpi_scan_init(void)if (result)acpi_device_unregister (acpi_root,ACPI_BUS_REMOVAL_NORMAL ); +else +acpi_update_gpes ();return result; }
drivers/acpi/dock.c +1 -0
@@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handcomplete_dock (ds);dock_event (ds, event,DOCK_EVENT );dock_lock (ds,1 ); +acpi_update_gpes ();break ; }if (dock_present (ds) ||dock_in_progress (ds))
Len Brown
reviewerRe: [Update][PATCH] ACPI / ACPICA: Defer enabling of runtime GPEs (v3)
applied to acpi-test
thanks,
Len Brown, Intel Open Source Technology Center