Re: [PATCH] ACPI/ACPICA: Run EC _REG explicitly for ECDT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Monday, January 7, 2019 1:43:29 PM CET Rafael J. Wysocki wrote:
> On Mon, Jan 7, 2019 at 12:51 PM Rafael J. Wysocki <rafael@xxxxxxxxxx> wrote:
> >
> >  ca   On Sat, Jan 5, 2019 at 2:17 PM Zhang Rui <rui.zhang@xxxxxxxxx> wrote:
> > >
> > > From 6f2fac0ffcd7fd61036baa0798ab171496cff50f Mon Sep 17 00:00:00 2001
> > > From: Zhang Rui <rui.zhang@xxxxxxxxx>
> > > Date: Fri, 4 Jan 2019 14:35:52 +0800
> > > Subject: [PATCH] ACPI/ACPICA: Run EC _REG explicitly for ECDT
> > >
> > > commit d737f333b211 ("ACPI: probe ECDT before loading AML tables
> > > regardless of module-level code flag") probes ECDT before loading
> > > the AML tables.
> > >
> > > This is the right thing to do according to the ACPI Spec, but
> > > unfortunately, it breaks the current kernel EC/ECDT support, and makes
> > > many devices, including battery, lid, etc, fails to work on a variety
> > > of platforms.
> > >
> > > This is because:
> > > 1. Probing ECDT requires installing EC address space handler
> > > 2. EC _REG can not be evaluated at the time when probing ECDT because AML
> > >    tables have not been loaded yet.
> > > 3. Many devices fail to work because EC _REG is not evaluated.
> > >
> > > To fix this, a solution is proposed in this patch to evaluate EC _REG
> > > explicitly in ACPICA, if ECDT has been probed.
> >
> > It would be good to give some more details here as the patch itself
> > appears to be rather convoluted.
> >
> > Also, the description above doesn't actually explain why the problem
> > is there, as it doesn't explain why probing the ECDT early causes the
> > EC _REG to be not evaluated.
> >
> > It looks like the failure is due to the change of the ordering between
> > acpi_load_tables() and acpi_ec_ecdt_probe() in the
> > acpi_gbl_group_module_level_code case which causes the EC to be probed
> > before instantiating the namespace and _REG obviously cannot be
> > evaluated then.
> 
> So what happens is:
> 
> acpi_ec_ecdt_probe()
>     acpi_ec_ecdt_probe()
>         acpi_config_boot_ec(ec, ACPI_ROOT_OBJECT, false, true)
>             ...
>             ec->handle = ACPI_ROOT_OBJECT;
>             ...
>             acpi_ec_setup(ec, false)
>                 ec_install_handlers(ec, false)
> 
> acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
> ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, NULL, ec)
>                     ...
>                     set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)
> 
> and now it returns, because handle_events is "false".
> 
> Next time acpi_ec_setup() is called from acpi_ec_add() that can be
> invoked in two ways, either through
> acpi_bus_register_driver(&acpi_ec_driver) which runs it for the DSDT
> EC (if found), or through acpi_ec_ecdt_start() and
> acpi_bus_register_early_device().
> 
> There are two cases in there, the acpi_config_boot_ec() one and the
> direct invocation of acpi_ec_setup() when acpi_is_boot_ec(ec) returns
> "false".  The former is the failing case AFAICS, because
> acpi_ec_ecdt_probe() (if successful) has set boot_ec as well as
> ec->command_addr and ec->data_addr.
> 
> So acpi_config_boot_ec() runs again and since boot_ec->handle has not
> been updated, it doesn't call ec_remove_handlers(), and because the
> EC_FLAGS_EC_HANDLER_INSTALLED is set, the address space handler
> installed previously is retained and _REG is not evaluated.  Since it
> wasn't evaluated before (as it was not present then), it is never
> evaluated and the failure occurs.
> 
> So it looks like clearing ec-> handle before invoking
> acpi_config_boot_ec() in the is_ecdt case in acpi_ec_add() can help,
> can't it?

Well, that wouldn't work, because ec->handle is checked by acpi_config_boot_ec()
too.  What might work would be to clear it and then pass the original to
acpi_config_boot_ec() as 'handle'.  Anyway, the patch below should cover
all of the different cases just fine, so can you try this one, please?

---
 drivers/acpi/ec.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

Index: linux-pm/drivers/acpi/ec.c
===================================================================
--- linux-pm.orig/drivers/acpi/ec.c
+++ linux-pm/drivers/acpi/ec.c
@@ -1545,12 +1545,13 @@ static int acpi_config_boot_ec(struct ac
 	int ret;
 
 	/*
-	 * Changing the ACPI handle results in a re-configuration of the
-	 * boot EC. And if it happens after the namespace initialization,
-	 * it causes _REG evaluations.
+	 * It is necessary to evaluate the _REG method for the EC address space
+	 * handler, but it might not be evaluated when installing that handler
+	 * previously (as that might happen when the namespace was not present
+	 * yet), so remove the handler at this point to force the evaluation of
+	 * _REG when it is installed again by acpi_ec_setup() below.
 	 */
-	if (boot_ec && boot_ec->handle != handle)
-		ec_remove_handlers(boot_ec);
+	ec_remove_handlers(ec);
 
 	/* Unset old boot EC */
 	if (boot_ec != ec)




[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux