Commit 0e6b6ded authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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: 60fa6ae6 ("ACPI: EC: Install address space handler at the namespace root")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218945


Reported-by: default avatarVitaliiT <vitaly.torshyn@gmail.com>
Tested-by: default avatarVitaliiT <vitaly.torshyn@gmail.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 83a7eefe
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -191,6 +191,10 @@ void
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
			    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_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);

+1 −5
Original line number Diff line number Diff line
@@ -20,10 +20,6 @@ extern u8 acpi_gbl_default_address_spaces[];

/* 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
acpi_ev_reg_run(acpi_handle obj_handle,
		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_adr_space_type space_id)
{
+54 −0
Original line number Diff line number Diff line
@@ -306,3 +306,57 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
}

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)
+3 −0
Original line number Diff line number Diff line
@@ -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)) {
		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);
	}

+4 −0
Original line number Diff line number Diff line
@@ -662,6 +662,10 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
			    acpi_execute_reg_methods(acpi_handle device,
						     acpi_adr_space_type
						     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_remove_address_space_handler(acpi_handle
							      device,