Commit 3d03140c authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'acpi-ec'

Merge additional ACPI EC driver fixes for 6.2-rc1:

 - Fix EC address space handler unregistration (Hans de Goede).

 - Defer the evaluation of _REG for ECDT described ECs till the matching
   EC device in the DSDT gets parsed and acpi_ec_add() gets called for
   it (Hans de Goede).

* acpi-ec:
  ACPI: EC: Fix ECDT probe ordering issues
  ACPI: EC: Fix EC address space handler unregistration
parents f7eae09b ab4620f5
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ enum {
	EC_FLAGS_QUERY_ENABLED,		/* Query is enabled */
	EC_FLAGS_EVENT_HANDLER_INSTALLED,	/* Event handler installed */
	EC_FLAGS_EC_HANDLER_INSTALLED,	/* OpReg handler installed */
	EC_FLAGS_EC_REG_CALLED,		/* OpReg ACPI _REG method called */
	EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */
	EC_FLAGS_STARTED,		/* Driver is started */
	EC_FLAGS_STOPPED,		/* Driver is stopped */
@@ -1446,6 +1447,7 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
 * ec_install_handlers - Install service callbacks and register query methods.
 * @ec: Target EC.
 * @device: ACPI device object corresponding to @ec.
 * @call_reg: If _REG should be called to notify OpRegion availability
 *
 * Install a handler for the EC address space type unless it has been installed
 * already.  If @device is not NULL, also look for EC query methods in the
@@ -1458,7 +1460,8 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
 * -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred,
 * or 0 (success) otherwise.
 */
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
			       bool call_reg)
{
	acpi_status status;

@@ -1466,7 +1469,7 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)

	if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
		acpi_ec_enter_noirq(ec);
		status = acpi_install_address_space_handler(ec->handle,
		status = acpi_install_address_space_handler_no_reg(ec->handle,
								   ACPI_ADR_SPACE_EC,
								   &acpi_ec_space_handler,
								   NULL, ec);
@@ -1475,6 +1478,12 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
			return -ENODEV;
		}
		set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
		ec->address_space_handler_holder = ec->handle;
	}

	if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
		acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
		set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
	}

	if (!device)
@@ -1526,7 +1535,8 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
static void ec_remove_handlers(struct acpi_ec *ec)
{
	if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
		if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
		if (ACPI_FAILURE(acpi_remove_address_space_handler(
					ec->address_space_handler_holder,
					ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
			pr_err("failed to remove space handler\n");
		clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
@@ -1562,11 +1572,11 @@ static void ec_remove_handlers(struct acpi_ec *ec)
	}
}

static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool call_reg)
{
	int ret;

	ret = ec_install_handlers(ec, device);
	ret = ec_install_handlers(ec, device, call_reg);
	if (ret)
		return ret;

@@ -1631,7 +1641,7 @@ static int acpi_ec_add(struct acpi_device *device)
		}
	}

	ret = acpi_ec_setup(ec, device);
	ret = acpi_ec_setup(ec, device, true);
	if (ret)
		goto err;

@@ -1750,7 +1760,7 @@ void __init acpi_ec_dsdt_probe(void)
	 * At this point, the GPE is not fully initialized, so do not to
	 * handle the events.
	 */
	ret = acpi_ec_setup(ec, NULL);
	ret = acpi_ec_setup(ec, NULL, true);
	if (ret) {
		acpi_ec_free(ec);
		return;
@@ -1944,7 +1954,7 @@ void __init acpi_ec_ecdt_probe(void)
	 * At this point, the namespace is not initialized, so do not find
	 * the namespace objects, or handle the events.
	 */
	ret = acpi_ec_setup(ec, NULL);
	ret = acpi_ec_setup(ec, NULL, false);
	if (ret) {
		acpi_ec_free(ec);
		goto out;
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ enum acpi_ec_event_state {

struct acpi_ec {
	acpi_handle handle;
	acpi_handle address_space_handler_holder;
	int gpe;
	int irq;
	unsigned long command_addr;