Skip to content

Commit 60fa6ae

Browse files
committed
ACPI: EC: Install address space handler at the namespace root
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. Reported-by: webcaptcha <webcapcha@gmail.com> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218789 Link: https://uefi.org/specs/ACPI/6.5/09_ACPI_Defined_Devices_and_Device_Specific_Objects.html#example-asl-code Link: https://lore.kernel.org/linux-acpi/Zi+0whTvDbAdveHq@kuha.fi.intel.com Suggested-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
1 parent ea5f6ad commit 60fa6ae

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

drivers/acpi/ec.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,13 +1482,14 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
14821482
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
14831483
bool call_reg)
14841484
{
1485+
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
14851486
acpi_status status;
14861487

14871488
acpi_ec_start(ec, false);
14881489

14891490
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
14901491
acpi_ec_enter_noirq(ec);
1491-
status = acpi_install_address_space_handler_no_reg(ec->handle,
1492+
status = acpi_install_address_space_handler_no_reg(scope_handle,
14921493
ACPI_ADR_SPACE_EC,
14931494
&acpi_ec_space_handler,
14941495
NULL, ec);
@@ -1497,11 +1498,10 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
14971498
return -ENODEV;
14981499
}
14991500
set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
1500-
ec->address_space_handler_holder = ec->handle;
15011501
}
15021502

15031503
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
1504-
acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
1504+
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
15051505
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
15061506
}
15071507

@@ -1553,10 +1553,13 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
15531553

15541554
static void ec_remove_handlers(struct acpi_ec *ec)
15551555
{
1556+
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
1557+
15561558
if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
15571559
if (ACPI_FAILURE(acpi_remove_address_space_handler(
1558-
ec->address_space_handler_holder,
1559-
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
1560+
scope_handle,
1561+
ACPI_ADR_SPACE_EC,
1562+
&acpi_ec_space_handler)))
15601563
pr_err("failed to remove space handler\n");
15611564
clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
15621565
}
@@ -1595,14 +1598,18 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool ca
15951598
{
15961599
int ret;
15971600

1598-
ret = ec_install_handlers(ec, device, call_reg);
1599-
if (ret)
1600-
return ret;
1601-
16021601
/* First EC capable of handling transactions */
16031602
if (!first_ec)
16041603
first_ec = ec;
16051604

1605+
ret = ec_install_handlers(ec, device, call_reg);
1606+
if (ret) {
1607+
if (ec == first_ec)
1608+
first_ec = NULL;
1609+
1610+
return ret;
1611+
}
1612+
16061613
pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr,
16071614
ec->data_addr);
16081615

drivers/acpi/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ enum acpi_ec_event_state {
186186

187187
struct acpi_ec {
188188
acpi_handle handle;
189-
acpi_handle address_space_handler_holder;
190189
int gpe;
191190
int irq;
192191
unsigned long command_addr;

0 commit comments

Comments
 (0)