ACPI: EC: Evaluate orphan _REG under EC device
After starting to install the EC address space handler at the ACPI
namespace root, if there is an "orphan" _REG method in the EC device's
scope, it will not be evaluated any more. This breaks EC operation
regions on some systems, like Asus gu605.
To address this, use a wrapper around an existing ACPICA function to
look for an "orphan" _REG method in the EC device scope and evaluate
it if present.
Fixes: 60fa6ae6e6
("ACPI: EC: Install address space handler at the namespace root")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218945
Reported-by: VitaliiT <vitaly.torshyn@gmail.com>
Tested-by: VitaliiT <vitaly.torshyn@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
83a7eefedc
commit
0e6b6dedf1
@ -191,6 +191,10 @@ 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);
|
||||||
|
|
||||||
|
void
|
||||||
|
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node,
|
||||||
|
acpi_adr_space_type space_id);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
|
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
|
||||||
|
|
||||||
|
@ -20,10 +20,6 @@ extern u8 acpi_gbl_default_address_spaces[];
|
|||||||
|
|
||||||
/* Local prototypes */
|
/* Local prototypes */
|
||||||
|
|
||||||
static void
|
|
||||||
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
|
|
||||||
acpi_adr_space_type space_id);
|
|
||||||
|
|
||||||
static acpi_status
|
static acpi_status
|
||||||
acpi_ev_reg_run(acpi_handle obj_handle,
|
acpi_ev_reg_run(acpi_handle obj_handle,
|
||||||
u32 level, void *context, void **return_value);
|
u32 level, void *context, void **return_value);
|
||||||
@ -818,7 +814,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static void
|
void
|
||||||
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
|
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
|
||||||
acpi_adr_space_type space_id)
|
acpi_adr_space_type space_id)
|
||||||
{
|
{
|
||||||
|
@ -306,3 +306,57 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
|
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_execute_orphan_reg_method
|
||||||
|
*
|
||||||
|
* PARAMETERS: device - Handle for the device
|
||||||
|
* space_id - The address space ID
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
|
||||||
|
* device. This is a _REG method that has no corresponding region
|
||||||
|
* within the device's scope.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
acpi_status
|
||||||
|
acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id)
|
||||||
|
{
|
||||||
|
struct acpi_namespace_node *node;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method);
|
||||||
|
|
||||||
|
/* Parameter validation */
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert and validate the device handle */
|
||||||
|
|
||||||
|
node = acpi_ns_validate_handle(device);
|
||||||
|
if (node) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If an "orphan" _REG method is present in the device's scope
|
||||||
|
* for the given address space ID, run it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
acpi_ev_execute_orphan_reg_method(node, space_id);
|
||||||
|
} else {
|
||||||
|
status = AE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method)
|
||||||
|
@ -1507,6 +1507,9 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
|||||||
|
|
||||||
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
|
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
|
||||||
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
|
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
|
||||||
|
if (scope_handle != ec->handle)
|
||||||
|
acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC);
|
||||||
|
|
||||||
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
|
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,6 +662,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
|||||||
acpi_execute_reg_methods(acpi_handle device,
|
acpi_execute_reg_methods(acpi_handle device,
|
||||||
acpi_adr_space_type
|
acpi_adr_space_type
|
||||||
space_id))
|
space_id))
|
||||||
|
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||||
|
acpi_execute_orphan_reg_method(acpi_handle device,
|
||||||
|
acpi_adr_space_type
|
||||||
|
space_id))
|
||||||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||||||
acpi_remove_address_space_handler(acpi_handle
|
acpi_remove_address_space_handler(acpi_handle
|
||||||
device,
|
device,
|
||||||
|
Loading…
Reference in New Issue
Block a user