Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 252766
b: refs/heads/master
c: e2066ca
h: refs/heads/master
v: v3
  • Loading branch information
Bob Moore authored and Len Brown committed May 10, 2011
1 parent 445de32 commit a32f63f
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 07aa99e9df2184e78068f7d5414e29e4a5a1b452
refs/heads/master: e2066ca1b211ff08325c98be9fb8ad95affbaba8
121 changes: 119 additions & 2 deletions trunk/drivers/acpi/acpica/evregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ static u8
acpi_ev_has_default_handler(struct acpi_namespace_node *node,
acpi_adr_space_type space_id);

static void acpi_ev_orphan_ec_reg_method(void);

static acpi_status
acpi_ev_reg_run(acpi_handle obj_handle,
u32 level, void *context, void **return_value);
Expand Down Expand Up @@ -561,7 +563,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,

/* Now stop region accesses by executing the _REG method */

status = acpi_ev_execute_reg_method(region_obj, 0);
status =
acpi_ev_execute_reg_method(region_obj,
ACPI_REG_DISCONNECT);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"from region _REG, [%s]",
Expand Down Expand Up @@ -1062,6 +1066,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
NULL, &space_id, 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();
}

return_ACPI_STATUS(status);
}

Expand Down Expand Up @@ -1120,6 +1130,113 @@ acpi_ev_reg_run(acpi_handle obj_handle,
return (AE_OK);
}

status = acpi_ev_execute_reg_method(obj_desc, 1);
status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
return (status);
}

/*******************************************************************************
*
* FUNCTION: acpi_ev_orphan_ec_reg_method
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
* 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_ID that appears
* within the ECDT. Otherwise, we would need to perform a time-
* consuming namespace walk, executing _HID methods to find the
* EC device.
*
******************************************************************************/

static void acpi_ev_orphan_ec_reg_method(void)
{
struct acpi_table_ecdt *table;
acpi_status status;
struct acpi_object_list args;
union acpi_object objects[2];
struct acpi_namespace_node *ec_device_node;
struct acpi_namespace_node *reg_method;
struct acpi_namespace_node *next_node;

ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);

/* Get the ECDT (if present in system) */

status = acpi_get_table(ACPI_SIG_ECDT, 0,
ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
&table));
if (ACPI_FAILURE(status)) {
return_VOID;
}

/* We need a valid EC_ID string */

if (!(*table->id)) {
return_VOID;
}

/* Namespace is currently locked, must release */

(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);

/* Get a handle to the EC device referenced in the ECDT */

status = acpi_get_handle(NULL,
ACPI_CAST_PTR(char, table->id),
ACPI_CAST_PTR(acpi_handle, &ec_device_node));
if (ACPI_FAILURE(status)) {
goto exit;
}

/* Get a handle to a _REG method immediately under the EC device */

status = acpi_get_handle(ec_device_node,
METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
&reg_method));
if (ACPI_FAILURE(status)) {
goto exit;
}

/*
* Execute the _REG method only if there is no Operation Region in
* this scope with the Embedded Controller space ID. Otherwise, it
* will already have been executed. Note, this allows for Regions
* with other space IDs to be present; but the code below will then
* execute the _REG method with the EC space ID argument.
*/
next_node = acpi_ns_get_next_node(ec_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)) {
goto exit; /* Do not execute _REG */
}
next_node = acpi_ns_get_next_node(ec_device_node, next_node);
}

/* Evaluate the _REG(EC,Connect) method */

args.count = 2;
args.pointer = objects;
objects[0].type = ACPI_TYPE_INTEGER;
objects[0].integer.value = ACPI_ADR_SPACE_EC;
objects[1].type = ACPI_TYPE_INTEGER;
objects[1].integer.value = ACPI_REG_CONNECT;

status = acpi_evaluate_object(reg_method, NULL, &args, NULL);

exit:
/* We ignore all errors from above, don't care */

status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
return_VOID;
}
2 changes: 1 addition & 1 deletion trunk/drivers/acpi/acpica/evrgnini.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,

status =
acpi_ev_execute_reg_method
(region_obj, 1);
(region_obj, ACPI_REG_CONNECT);

if (acpi_ns_locked) {
status =
Expand Down
13 changes: 7 additions & 6 deletions trunk/drivers/acpi/acpica/evxfregn.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,20 +130,21 @@ acpi_install_address_space_handler(acpi_handle device,
case ACPI_ADR_SPACE_PCI_CONFIG:
case ACPI_ADR_SPACE_DATA_TABLE:

if (acpi_gbl_reg_methods_executed) {
if (!acpi_gbl_reg_methods_executed) {

/* Run all _REG methods for this address space */

status = acpi_ev_execute_reg_methods(node, space_id);
/* We will defer execution of the _REG methods for this space */
goto unlock_and_exit;
}
break;

default:

status = acpi_ev_execute_reg_methods(node, space_id);
break;
}

/* Run all _REG methods for this address space */

status = acpi_ev_execute_reg_methods(node, space_id);

unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_ACPI_STATUS(status);
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/acpi/actypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,11 @@ typedef u8 acpi_adr_space_type;
#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 0x7E /* Internal to ACPICA only */
#define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 0x7F

/* Values for _REG connection code */

#define ACPI_REG_DISCONNECT 0
#define ACPI_REG_CONNECT 1

/*
* bit_register IDs
*
Expand Down

0 comments on commit a32f63f

Please sign in to comment.