forked from Minki/linux
ACPICA: Events: Fix an issue that _REG association can happen before namespace is initialized
ACPICA commit c508f8592efaa0d8197f26d7fee6382c5ac8e383 Current code flow cannot ensure _REG association can happen after the namespace is initialized, so we move _REG association to where _REG was about to run to fix this issue. This issue is detected when acpi_ev_initialize_region() is invoked during the table loading. And this is one of the most important the root cause why ACPICA table loading is split into 2 load passes. Lv Zheng. Link: https://github.com/acpica/acpica/commit/c508f859 Link: https://bugs.acpica.org/show_bug.cgi?id=1252 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
ca4fc02714
commit
d1461a1b50
@ -198,8 +198,6 @@ void
|
|||||||
acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
acpi_ev_detach_region(union acpi_operand_object *region_obj,
|
||||||
u8 acpi_ns_is_locked);
|
u8 acpi_ns_is_locked);
|
||||||
|
|
||||||
void acpi_ev_associate_reg_method(union acpi_operand_object *region_obj);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||||
acpi_adr_space_type space_id, u32 function);
|
acpi_adr_space_type space_id, u32 function);
|
||||||
|
@ -524,53 +524,6 @@ acpi_ev_attach_region(union acpi_operand_object *handler_obj,
|
|||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_associate_reg_method
|
|
||||||
*
|
|
||||||
* PARAMETERS: region_obj - Region object
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Find and associate _REG method to a region
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
void acpi_ev_associate_reg_method(union acpi_operand_object *region_obj)
|
|
||||||
{
|
|
||||||
const acpi_name *reg_name_ptr =
|
|
||||||
ACPI_CAST_PTR(acpi_name, METHOD_NAME__REG);
|
|
||||||
struct acpi_namespace_node *method_node;
|
|
||||||
struct acpi_namespace_node *node;
|
|
||||||
union acpi_operand_object *region_obj2;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_associate_reg_method);
|
|
||||||
|
|
||||||
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
|
||||||
if (!region_obj2) {
|
|
||||||
return_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = region_obj->region.node->parent;
|
|
||||||
|
|
||||||
/* Find any "_REG" method associated with this region definition */
|
|
||||||
|
|
||||||
status =
|
|
||||||
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
|
|
||||||
&method_node);
|
|
||||||
if (ACPI_SUCCESS(status)) {
|
|
||||||
/*
|
|
||||||
* The _REG method is optional and there can be only one per region
|
|
||||||
* definition. This will be executed when the handler is attached
|
|
||||||
* or removed
|
|
||||||
*/
|
|
||||||
region_obj2->extra.method_REG = method_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_execute_reg_method
|
* FUNCTION: acpi_ev_execute_reg_method
|
||||||
@ -590,18 +543,42 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
|||||||
struct acpi_evaluate_info *info;
|
struct acpi_evaluate_info *info;
|
||||||
union acpi_operand_object *args[3];
|
union acpi_operand_object *args[3];
|
||||||
union acpi_operand_object *region_obj2;
|
union acpi_operand_object *region_obj2;
|
||||||
|
const acpi_name *reg_name_ptr =
|
||||||
|
ACPI_CAST_PTR(acpi_name, METHOD_NAME__REG);
|
||||||
|
struct acpi_namespace_node *method_node;
|
||||||
|
struct acpi_namespace_node *node;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
|
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
|
||||||
|
|
||||||
|
if (!acpi_gbl_namespace_initialized ||
|
||||||
|
region_obj->region.handler == NULL) {
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
region_obj2 = acpi_ns_get_secondary_object(region_obj);
|
||||||
if (!region_obj2) {
|
if (!region_obj2) {
|
||||||
return_ACPI_STATUS(AE_NOT_EXIST);
|
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region_obj2->extra.method_REG == NULL ||
|
/*
|
||||||
region_obj->region.handler == NULL ||
|
* Find any "_REG" method associated with this region definition.
|
||||||
!acpi_gbl_namespace_initialized) {
|
* The method should always be updated as this function may be
|
||||||
|
* invoked after a namespace change.
|
||||||
|
*/
|
||||||
|
node = region_obj->region.node->parent;
|
||||||
|
status =
|
||||||
|
acpi_ns_search_one_scope(*reg_name_ptr, node, ACPI_TYPE_METHOD,
|
||||||
|
&method_node);
|
||||||
|
if (ACPI_SUCCESS(status)) {
|
||||||
|
/*
|
||||||
|
* The _REG method is optional and there can be only one per
|
||||||
|
* region definition. This will be executed when the handler is
|
||||||
|
* attached or removed.
|
||||||
|
*/
|
||||||
|
region_obj2->extra.method_REG = method_node;
|
||||||
|
}
|
||||||
|
if (region_obj2->extra.method_REG == NULL) {
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +518,6 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
|||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_ev_associate_reg_method(region_obj);
|
|
||||||
region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
|
region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
|
||||||
|
|
||||||
node = region_obj->region.node->parent;
|
node = region_obj->region.node->parent;
|
||||||
|
Loading…
Reference in New Issue
Block a user