@@ -21,7 +21,8 @@ extern u8 acpi_gbl_default_address_spaces[];
/* Local prototypes */
static void
-acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node);
+acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
+ acpi_adr_space_type space_id);
static acpi_status
acpi_ev_reg_run(acpi_handle obj_handle,
@@ -684,10 +685,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL,
&info, NULL);
- /* Special case for EC: handle "orphan" _REG methods with no region */
-
- if (space_id == ACPI_ADR_SPACE_EC) {
- acpi_ev_orphan_ec_reg_method(node);
+ /*
+ * Special case for EC and GPIO: handle "orphan" _REG methods with
+ * no region.
+ */
+ if (space_id == ACPI_ADR_SPACE_EC || space_id == ACPI_ADR_SPACE_GPIO) {
+ acpi_ev_execute_orphan_reg_method(node, space_id);
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES,
@@ -760,31 +763,28 @@ acpi_ev_reg_run(acpi_handle obj_handle,
/*******************************************************************************
*
- * FUNCTION: acpi_ev_orphan_ec_reg_method
+ * FUNCTION: acpi_ev_execute_orphan_reg_method
*
- * PARAMETERS: ec_device_node - Namespace node for an EC device
+ * PARAMETERS: device_node - Namespace node for an ACPI device
+ * space_id - The address space ID
*
* RETURN: None
*
- * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
+ * DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
* device. This is a _REG method that has no corresponding region
- * within the EC device scope. The orphan _REG method appears to
- * have been enabled by the description of the ECDT in the ACPI
- * specification: "The availability of the region space can be
- * detected by providing a _REG method object underneath the
- * Embedded Controller device."
- *
- * To quickly access the EC device, we use the ec_device_node used
- * during EC handler installation. Otherwise, we would need to
- * perform a time consuming namespace walk, executing _HID
- * methods to find the EC device.
+ * within the device's scope. ACPI tables depending on these
+ * "orphan" _REG methods have been seen for both EC and GPIO
+ * Operation Regions. Presumably the Windows ACPI implementation
+ * always calls the _REG method independent of the presence of
+ * an actual Operation Region with the correct address space ID.
*
* MUTEX: Assumes the namespace is locked
*
******************************************************************************/
static void
-acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
+acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
+ acpi_adr_space_type space_id)
{
acpi_handle reg_method;
struct acpi_namespace_node *next_node;
@@ -792,9 +792,9 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
struct acpi_object_list args;
union acpi_object objects[2];
- ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
+ ACPI_FUNCTION_TRACE(ev_execute_orphan_reg_method);
- if (!ec_device_node) {
+ if (!device_node) {
return_VOID;
}
@@ -804,7 +804,7 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
/* Get a handle to a _REG method immediately under the EC device */
- status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method);
+ status = acpi_get_handle(device_node, METHOD_NAME__REG, ®_method);
if (ACPI_FAILURE(status)) {
goto exit; /* There is no _REG method present */
}
@@ -816,23 +816,23 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
* with other space IDs to be present; but the code below will then
* execute the _REG method with the embedded_control space_ID argument.
*/
- next_node = acpi_ns_get_next_node(ec_device_node, NULL);
+ next_node = acpi_ns_get_next_node(device_node, NULL);
while (next_node) {
if ((next_node->type == ACPI_TYPE_REGION) &&
(next_node->object) &&
- (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
+ (next_node->object->region.space_id == space_id)) {
goto exit; /* Do not execute the _REG */
}
- next_node = acpi_ns_get_next_node(ec_device_node, next_node);
+ next_node = acpi_ns_get_next_node(device_node, next_node);
}
- /* Evaluate the _REG(embedded_control,Connect) method */
+ /* Evaluate the _REG(space_id,Connect) method */
args.count = 2;
args.pointer = objects;
objects[0].type = ACPI_TYPE_INTEGER;
- objects[0].integer.value = ACPI_ADR_SPACE_EC;
+ objects[0].integer.value = space_id;
objects[1].type = ACPI_TYPE_INTEGER;
objects[1].integer.value = ACPI_REG_CONNECT;