Bob, what do you think of this patch? Should we have an ACPICA style patch first and fix the problem in next ACPICA release? or should I submit the patch to Linux/ACPI first? >From c1fc8a40c521065ed35e14b44261760bf5cdcd4e Mon Sep 17 00:00:00 2001 From: Zhang Rui <rui.zhang@xxxxxxxxx> Date: Fri, 30 Nov 2012 10:25:50 +0800 Subject: [PATCH] Execute "orphan" _REG method for specified EC device Some platforms do not have EC address space Operation Region. But the AML code depends on EC._REG being invoked to work properly. The AML code is broken on such platforms because _REG is only evaluated when there is at least one EC Operation Region. commit e2066ca1b211ff08325c98be9fb8ad95affbaba8 Author: Bob Moore <robert.moore@xxxxxxxxx> Date: Wed Apr 13 13:22:04 2011 +0800 ACPICA: Execute an orphan _REG method under the EC device This change will force the execution of a _REG method underneath the EC device even if there is no corresponding operation region of type EmbeddedControl. Fixes a problem seen on some machines and apparently is compatible with Windows behavior. http://www.acpica.org/bugzilla/show_bug.cgi?id=875 Signed-off-by: Bob Moore <robert.moore@xxxxxxxxx> Signed-off-by: Lin Ming <ming.m.lin@xxxxxxxxx> Signed-off-by: Len Brown <len.brown@xxxxxxxxx> Robert Moore has a patch to fix the issue, but the problem is that this patch only fixes the problem on platforms with ECDT. Thus the AML code is still broken in bug report: https://bugzilla.kernel.org/show_bug.cgi?id=15707 This patch makes some enhancement, and it should work for all the platforms, even if there is no ECDT. Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx> --- drivers/acpi/acpica/evregion.c | 42 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 0cc6a16..76af11e 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -55,7 +55,7 @@ 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 void acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *node); static acpi_status acpi_ev_reg_run(acpi_handle obj_handle, @@ -1092,7 +1092,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, /* Special case for EC: handle "orphan" _REG methods with no region */ if (space_id == ACPI_ADR_SPACE_EC) { - acpi_ev_orphan_ec_reg_method(); + acpi_ev_orphan_ec_reg_method(node); } return_ACPI_STATUS(status); @@ -1161,7 +1161,7 @@ acpi_ev_reg_run(acpi_handle obj_handle, * * FUNCTION: acpi_ev_orphan_ec_reg_method * - * PARAMETERS: None + * PARAMETERS: node - Namespace node for the device * * RETURN: None * @@ -1180,51 +1180,29 @@ acpi_ev_reg_run(acpi_handle obj_handle, * ******************************************************************************/ -static void acpi_ev_orphan_ec_reg_method(void) +static void acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *node) { 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)) { + /* Get the EC node */ + if (!node) 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, - ®_method)); + status = acpi_get_handle(node, METHOD_NAME__REG, + ACPI_CAST_PTR(acpi_handle, ®_method)); if (ACPI_FAILURE(status)) { goto exit; } @@ -1236,14 +1214,14 @@ static void acpi_ev_orphan_ec_reg_method(void) * 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); + next_node = acpi_ns_get_next_node(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); + next_node = acpi_ns_get_next_node(node, next_node); } /* Evaluate the _REG(EC,Connect) method */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html