Message ID | 6046110.lOV4Wx5bFT@kreacher (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | ACPI: EC: Install EC address space handler at the namespace root | expand |
On Wed, May 15, 2024 at 09:40:54PM +0200, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo > IdeaPad Pro 5 due to a missing address space handler for the EC address > space: > > ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) > > This happens because if there is no ECDT, the EC driver only registers > the EC address space handler for operation regions defined in the EC > device scope of the ACPI namespace while the operation region being > accessed by the _DSM in question is located beyond that scope. > > To address this, modify the ACPI EC driver to install the EC address > space handler at the root of the ACPI namespace for the first EC that > can be found regardless of whether or not an ECDT is present. > > Note that this change is consistent with some examples in the ACPI > specification in which EC operation regions located outside the EC > device scope are used (for example, see Section 9.17.15 in ACPI 6.5), > so the current behavior of the EC driver is arguably questionable. ... > - status = acpi_install_address_space_handler_no_reg(ec->handle, > + status = acpi_install_address_space_handler_no_reg(scope_handle, > ACPI_ADR_SPACE_EC, > &acpi_ec_space_handler, > NULL, ec); Looking at this... > if (ACPI_FAILURE(acpi_remove_address_space_handler( > + scope_handle, > + ACPI_ADR_SPACE_EC, > + &acpi_ec_space_handler))) ...and this, I believe you can move scope_handle to the previous line and align the rest for the sake of consistency and slightly better readability.
On Thu, May 16, 2024 at 12:22 PM Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote: > > On Wed, May 15, 2024 at 09:40:54PM +0200, Rafael J. Wysocki wrote: > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > > > It is reported that _DSM evaluation fails in ucsi_acpi_dsm() on Lenovo > > IdeaPad Pro 5 due to a missing address space handler for the EC address > > space: > > > > ACPI Error: No handler for Region [ECSI] (000000007b8176ee) [EmbeddedControl] (20230628/evregion-130) > > > > This happens because if there is no ECDT, the EC driver only registers > > the EC address space handler for operation regions defined in the EC > > device scope of the ACPI namespace while the operation region being > > accessed by the _DSM in question is located beyond that scope. > > > > To address this, modify the ACPI EC driver to install the EC address > > space handler at the root of the ACPI namespace for the first EC that > > can be found regardless of whether or not an ECDT is present. > > > > Note that this change is consistent with some examples in the ACPI > > specification in which EC operation regions located outside the EC > > device scope are used (for example, see Section 9.17.15 in ACPI 6.5), > > so the current behavior of the EC driver is arguably questionable. > > ... > > > - status = acpi_install_address_space_handler_no_reg(ec->handle, > > + status = acpi_install_address_space_handler_no_reg(scope_handle, > > ACPI_ADR_SPACE_EC, > > &acpi_ec_space_handler, > > NULL, ec); > > Looking at this... > > > if (ACPI_FAILURE(acpi_remove_address_space_handler( > > + scope_handle, > > + ACPI_ADR_SPACE_EC, > > + &acpi_ec_space_handler))) > > ...and this, I believe you can move scope_handle to the previous line and align > the rest for the sake of consistency and slightly better readability. Well, I prefer to cut a separate cleanup patch to make this more consistent.
Index: linux-pm/drivers/acpi/ec.c =================================================================== --- linux-pm.orig/drivers/acpi/ec.c +++ linux-pm/drivers/acpi/ec.c @@ -1482,13 +1482,14 @@ static bool install_gpio_irq_event_handl static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, bool call_reg) { + acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; acpi_status status; acpi_ec_start(ec, false); if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { acpi_ec_enter_noirq(ec); - status = acpi_install_address_space_handler_no_reg(ec->handle, + status = acpi_install_address_space_handler_no_reg(scope_handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, NULL, ec); @@ -1497,11 +1498,10 @@ static int ec_install_handlers(struct ac 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); + acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC); set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags); } @@ -1553,10 +1553,13 @@ static int ec_install_handlers(struct ac static void ec_remove_handlers(struct acpi_ec *ec) { + acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle; + if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { if (ACPI_FAILURE(acpi_remove_address_space_handler( - ec->address_space_handler_holder, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) + scope_handle, + 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); } @@ -1595,14 +1598,18 @@ static int acpi_ec_setup(struct acpi_ec { int ret; - ret = ec_install_handlers(ec, device, call_reg); - if (ret) - return ret; - /* First EC capable of handling transactions */ if (!first_ec) first_ec = ec; + ret = ec_install_handlers(ec, device, call_reg); + if (ret) { + if (ec == first_ec) + first_ec = NULL; + + return ret; + } + pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr, ec->data_addr); Index: linux-pm/drivers/acpi/internal.h =================================================================== --- linux-pm.orig/drivers/acpi/internal.h +++ linux-pm/drivers/acpi/internal.h @@ -186,7 +186,6 @@ 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;