diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 899d68afc3c5e0bde9be08338ec14399e52c7d32..18e796fe429595af3c92787ccd8a66c5c2d275c9 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -99,13 +99,6 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); -/* - * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and - * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only - * be enabled just before going to sleep. - */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); - /* * Optionally use default values for the ACPI register widths. Set this to * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index f5795915a2e9cd72618fc28b3edb147d59bc4718..303618889da0a73a65a5d8ff8c79600cc90e6254 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -102,9 +102,8 @@ acpi_status acpi_ev_initialize_events(void) * RETURN: Status * * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks - * (0 and 1). This causes the _PRW methods to be run, so the HW - * must be fully initialized at this point, including global lock - * support. + * (0 and 1). The HW must be fully initialized at this point, + * including global lock support. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 0c6f3f878eb5d516eb547f7350ad7858e6e529d0..12ca1bc5f1fddf0a6dc2c9c4ebe7f655c20de142 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -439,8 +439,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, { acpi_status status; struct acpi_gpe_event_info *gpe_event_info; - struct acpi_gpe_walk_info walk_info; - u32 wake_gpe_count; u32 gpe_enabled_count; u32 gpe_index; u32 gpe_number; @@ -456,37 +454,9 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, } /* - * Runtime option: Should wake GPEs be enabled at runtime? The default - * is no, they should only be enabled just as the machine goes to sleep. + * Enable all GPEs that have a corresponding method. Any other GPEs + * within this block must be enabled via the acpi_enable_gpe interface. */ - if (acpi_gbl_leave_wake_gpes_disabled) { - /* - * Differentiate runtime vs wake GPEs, via the _PRW control methods. - * Each GPE that has one or more _PRWs that reference it is by - * definition a wake GPE and will not be enabled while the machine - * is running. - */ - walk_info.gpe_block = gpe_block; - walk_info.gpe_device = gpe_device; - walk_info.execute_by_owner_id = FALSE; - - status = - acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - acpi_ev_match_prw_and_gpe, NULL, - &walk_info, NULL); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While executing _PRW methods")); - } - } - - /* - * Enable all GPEs that have a corresponding method and are not - * capable of generating wakeups. Any other GPEs within this block - * must be enabled via the acpi_enable_gpe interface. - */ - wake_gpe_count = 0; gpe_enabled_count = 0; if (gpe_device == acpi_gbl_fadt_gpe_device) { @@ -512,13 +482,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, goto enabled; } - if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { - wake_gpe_count++; - if (acpi_gbl_leave_wake_gpes_disabled) { - continue; - } - } - /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { @@ -540,10 +503,10 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, } } - if (gpe_enabled_count || wake_gpe_count) { + if (gpe_enabled_count) { ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n", - gpe_enabled_count, wake_gpe_count)); + "Enabled %u GPEs in this block\n", + gpe_enabled_count)); } return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 8db9e076a53b87cf75e0ac7aed5ac02524f4370f..3084c5de1bba1b2a22c8ca2324a885ad6838b058 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -211,9 +211,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. Also, - * run any newly loaded _PRW methods in order to discover any - * new CAN_WAKE GPEs. + * enable and runtime GPEs that are associated with them. * ******************************************************************************/ @@ -223,49 +221,12 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_walk_info walk_info; acpi_status status = AE_OK; - u32 new_wake_gpe_count = 0; - - /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */ - - walk_info.owner_id = table_owner_id; - walk_info.execute_by_owner_id = TRUE; - walk_info.count = 0; - - if (acpi_gbl_leave_wake_gpes_disabled) { - /* - * 1) Run any newly-loaded _PRW methods to find any GPEs that - * can now be marked as CAN_WAKE GPEs. Note: We must run the - * _PRW methods before we process the _Lxx/_Exx methods because - * we will enable all runtime GPEs associated with the new - * _Lxx/_Exx methods at the time we process those methods. - * - * Unlock interpreter so that we can run the _PRW methods. - */ - walk_info.gpe_block = NULL; - walk_info.gpe_device = NULL; - - acpi_ex_exit_interpreter(); - - status = - acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, - ACPI_NS_WALK_NO_UNLOCK, - acpi_ev_match_prw_and_gpe, NULL, - &walk_info, NULL); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "While executing _PRW methods")); - } - - acpi_ex_enter_interpreter(); - new_wake_gpe_count = walk_info.count; - } /* * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. * - * Any GPEs that correspond to new _Lxx/_Exx methods and are not - * marked as CAN_WAKE are immediately enabled. + * Any GPEs that correspond to new _Lxx/_Exx methods are immediately + * enabled. * * Examine the namespace underneath each gpe_device within the * gpe_block lists. @@ -275,6 +236,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) return; } + walk_info.owner_id = table_owner_id; + walk_info.execute_by_owner_id = TRUE; walk_info.count = 0; walk_info.enable_this_gpe = TRUE; @@ -307,10 +270,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) gpe_xrupt_info = gpe_xrupt_info->next; } - if (walk_info.count || new_wake_gpe_count) { - ACPI_INFO((AE_INFO, - "Enabled %u new runtime GPEs, added %u new wakeup GPEs", - walk_info.count, new_wake_gpe_count)); + if (walk_info.count) { + ACPI_INFO((AE_INFO, "Enabled %u new GPEs", walk_info.count)); } (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); @@ -386,9 +347,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, /* * 3) Edge/Level determination is based on the 2nd character * of the method name - * - * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is - * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set. */ switch (name[1]) { case 'L': @@ -471,23 +429,18 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, */ if (walk_info->enable_this_gpe) { - /* Ignore GPEs that can wake the system */ + walk_info->count++; + gpe_device = walk_info->gpe_device; - if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE) || - !acpi_gbl_leave_wake_gpes_disabled) { - walk_info->count++; - gpe_device = walk_info->gpe_device; - - if (gpe_device == acpi_gbl_fadt_gpe_device) { - gpe_device = NULL; - } + 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)); - } + 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)); } } @@ -496,157 +449,3 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, name, gpe_number)); return_ACPI_STATUS(AE_OK); } - -/******************************************************************************* - * - * FUNCTION: acpi_ev_match_prw_and_gpe - * - * PARAMETERS: Callback from walk_namespace - * - * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is - * not aborted on a single _PRW failure. - * - * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a - * Device. Run the _PRW method. If present, extract the GPE - * number and mark the GPE as a CAN_WAKE GPE. Allows a - * per-owner_id execution if execute_by_owner_id is TRUE in the - * walk_info parameter block. - * - * If walk_info->execute_by_owner_id is TRUE, we only execute _PRWs with that - * owner. - * If walk_info->gpe_device is NULL, we execute every _PRW found. Otherwise, - * we only execute _PRWs that refer to the input gpe_device. - * - ******************************************************************************/ - -acpi_status -acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, - u32 level, void *context, void **return_value) -{ - struct acpi_gpe_walk_info *walk_info = - ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); - struct acpi_namespace_node *gpe_device; - struct acpi_gpe_block_info *gpe_block; - struct acpi_namespace_node *target_gpe_device; - struct acpi_namespace_node *prw_node; - struct acpi_gpe_event_info *gpe_event_info; - union acpi_operand_object *pkg_desc; - union acpi_operand_object *obj_desc; - u32 gpe_number; - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe); - - /* Check for a _PRW method under this device */ - - status = acpi_ns_get_node(obj_handle, METHOD_NAME__PRW, - ACPI_NS_NO_UPSEARCH, &prw_node); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(AE_OK); - } - - /* Check if requested owner_id matches this owner_id */ - - if ((walk_info->execute_by_owner_id) && - (prw_node->owner_id != walk_info->owner_id)) { - return_ACPI_STATUS(AE_OK); - } - - /* Execute the _PRW */ - - status = acpi_ut_evaluate_object(prw_node, NULL, - ACPI_BTYPE_PACKAGE, &pkg_desc); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(AE_OK); - } - - /* The returned _PRW package must have at least two elements */ - - if (pkg_desc->package.count < 2) { - goto cleanup; - } - - /* Extract pointers from the input context */ - - gpe_device = walk_info->gpe_device; - gpe_block = walk_info->gpe_block; - - /* - * The _PRW object must return a package, we are only interested - * in the first element - */ - obj_desc = pkg_desc->package.elements[0]; - - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - - /* Use FADT-defined GPE device (from definition of _PRW) */ - - target_gpe_device = NULL; - if (gpe_device) { - target_gpe_device = acpi_gbl_fadt_gpe_device; - } - - /* Integer is the GPE number in the FADT described GPE blocks */ - - gpe_number = (u32)obj_desc->integer.value; - } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - - /* Package contains a GPE reference and GPE number within a GPE block */ - - if ((obj_desc->package.count < 2) || - ((obj_desc->package.elements[0])->common.type != - ACPI_TYPE_LOCAL_REFERENCE) || - ((obj_desc->package.elements[1])->common.type != - ACPI_TYPE_INTEGER)) { - goto cleanup; - } - - /* Get GPE block reference and decode */ - - target_gpe_device = - obj_desc->package.elements[0]->reference.node; - gpe_number = (u32)obj_desc->package.elements[1]->integer.value; - } else { - /* Unknown type, just ignore it */ - - goto cleanup; - } - - /* Get the gpe_event_info for this GPE */ - - if (gpe_device) { - /* - * Is this GPE within this block? - * - * TRUE if and only if these conditions are true: - * 1) The GPE devices match. - * 2) The GPE index(number) is within the range of the Gpe Block - * associated with the GPE device. - */ - if (gpe_device != target_gpe_device) { - goto cleanup; - } - - gpe_event_info = - acpi_ev_low_get_gpe_info(gpe_number, gpe_block); - } else { - /* gpe_device is NULL, just match the target_device and gpe_number */ - - gpe_event_info = - acpi_ev_get_gpe_event_info(target_gpe_device, gpe_number); - } - - if (gpe_event_info) { - if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { - - /* This GPE can wake the system */ - - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - walk_info->count++; - } - } - - cleanup: - acpi_ut_remove_reference(pkg_desc); - return_ACPI_STATUS(AE_OK); -} diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index fda5b44a5567e3f393bb71b8e5eae6f83db3e228..bd06fad83e7a39fe43c9e07f82f1c200332bfb18 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -387,6 +387,59 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) } ACPI_EXPORT_SYMBOL(acpi_disable_gpe) +/******************************************************************************* + * + * FUNCTION: acpi_gpe_can_wake + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE + * has a corresponding method and is currently enabled, disable it + * (GPEs with corresponding methods are enabled unconditionally + * during initialization, but GPEs that can wake up are expected + * to be initially disabled). + * + ******************************************************************************/ +acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; + acpi_cpu_flags flags; + u8 disable = 0; + + ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* 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) { + 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; + disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) + && gpe_event_info->runtime_count; + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + + if (disable) + status = acpi_disable_gpe(gpe_device, gpe_number); + + return_ACPI_STATUS(status); +} +ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) + /******************************************************************************* * * FUNCTION: acpi_disable_event @@ -703,7 +756,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, obj_desc->device.gpe_block = gpe_block; - /* Run the _PRW methods and enable the runtime GPEs in the new block */ + /* Enable the runtime GPEs in the new block */ status = acpi_ev_initialize_gpe_block(node, gpe_block); diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 008621c5ad851d39048eef2602b19e6dd990810c..18832205b631b4514941490f86adb308914dc10e 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -120,7 +120,7 @@ acpi_ex_add_table(u32 table_index, acpi_ns_exec_module_code_list(); acpi_ex_enter_interpreter(); - /* Update GPEs for any new _PRW or _Lxx/_Exx methods. Ignore errors */ + /* Update GPEs for any new _Lxx/_Exx methods. Ignore errors */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index db9d8ca57987bc53b902274bb48a704438dbb525..7f8cefcb2b32da538adb9a2fb73e4dbae645924e 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -293,12 +293,8 @@ acpi_status acpi_initialize_objects(u32 flags) * Complete the GPE initialization for the GPE blocks defined in the FADT * (GPE block 0 and 1). * - * Note1: This is where the _PRW methods are executed for the GPEs. These - * methods can only be executed after the SCI and Global Lock handlers are - * installed and initialized. - * - * Note2: Currently, there seems to be no need to run the _REG methods - * before execution of the _PRW methods and enabling of the GPEs. + * 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(); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 78418ce4fc78a5cf99203e7890f81f36e23a10a8..44bddc5bc6adfae35187586a2c05ed5d72a7041e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1064,26 +1064,6 @@ static int __init acpi_serialize_setup(char *str) __setup("acpi_serialize", acpi_serialize_setup); -/* - * Wake and Run-Time GPES are expected to be separate. - * We disable wake-GPEs at run-time to prevent spurious - * interrupts. - * - * However, if a system exists that shares Wake and - * Run-time events on the same GPE this flag is available - * to tell Linux to keep the wake-time GPEs enabled at run-time. - */ -static int __init acpi_wake_gpes_always_on_setup(char *str) -{ - printk(KERN_INFO PREFIX "wake GPEs not disabled\n"); - - acpi_gbl_leave_wake_gpes_disabled = FALSE; - - return 1; -} - -__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); - /* Check of resource interference between native drivers and ACPI * OperationRegions (SystemIO and System Memory only). * IO ports and memory declared in ACPI might be used by the ACPI subsystem diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 449ada016d81278861d24bddfe070c6bc5bf261e..b23825ecfa372c192ff92fcf79b36c6534332e9c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -740,6 +740,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, device->wakeup.resources.handles[i] = element->reference.handle; } + acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); + return AE_OK; } diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index ba94a889afd15d2b4beb710e152abf022e4c24f3..81d4f3d4b9fdc70ff75ddda26f1fc0c65a8f7c7b 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -63,7 +63,6 @@ extern u32 acpi_dbg_layer; extern u8 acpi_gbl_enable_interpreter_slack; extern u8 acpi_gbl_all_methods_serialized; extern u8 acpi_gbl_create_osi_method; -extern u8 acpi_gbl_leave_wake_gpes_disabled; extern u8 acpi_gbl_use_default_register_widths; extern acpi_name acpi_gbl_trace_method_name; extern u32 acpi_gbl_trace_flags; @@ -286,6 +285,8 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); +acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number); + acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action);