mbox series

[RFC,0/4] ACPI[CA]: fix ECDT EC probe ordering issues

Message ID 20220615195643.12608-1-hdegoede@redhat.com
Headers show
Series ACPI[CA]: fix ECDT EC probe ordering issues | expand

Message

Hans de Goede June 15, 2022, 7:56 p.m. UTC
Hi All,

This series fixes some ECDT EC probe ordering issues which are causing
issues om some laptops:

https://bugzilla.kernel.org/show_bug.cgi?id=214899
https://bugzilla.redhat.com/show_bug.cgi?id=1842039

This is a RFC because fixing this requires some ACPICA changes which
obviously need to go upstream through the ACPICA project. But first
I wanted to try and get some general feedback on the chosen approach.

The problem this fixed is best described by the commit message of patch 4:

ACPI-2.0 says that the EC OpRegion handler must be available immediately
(like the standard default OpRegion handlers). So acpi_bus_init() calls
acpi_ec_ecdt_probe(), which calls acpi_install_address_space_handler() to
install the EC's OpRegion handler, early on.

This not only installs the OpRegion handler, but also calls the EC's
_REG method. The _REG method call is a problem because it may rely on
initialization done by the _INI methods of one of the PCI / _SB root devs,
see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .

This _REG depends on _INI problem can be fixed by calling the new ACPICA
acpi_early_initialize_objects() function before acpi_ec_ecdt_probe().

But on some boards (e.g. Lenovo X1C8) the root devices _INI method
relies on the EC OpRegion so executing the _INI methods before
registering the EC OpRegion handler leads to errors there.

To allow fixing this the ACPICA code now allows to do the OpRegion handler
installation early on (without calling _REG) and to do the EC's _REG
execution later on as a separate step.

This commit uses this new ACPICA functions to fix the EC probe ordering
by changing the acpi_bus_init() initialization order to this:

1. acpi_load_tables()
2. acpi_ec_ecdt_probe()
   This now calls acpi_install_address_space_handler(ACPI_NO_EXEC__REG)
   which installs the OpRegion handler without executing _REG
3. acpi_enable_subsystem()
4. acpi_early_initialize_objects()
   This calls the _INI method of the PCI and _SB root devices
5. acpi_ec_ecdt_exec_reg();
   This executes the EC's _REG now that the root devices _INI has run
6. acpi_initialize_objects(ACPI_NO_EARLY_DEVICE_INIT)

This allows the EC's _REG method to depend on e.g. the \OSYS global/GVNS
variable often set by a root-device's _INI method, while at the same time
allowing these _INI methods to access EmbeddedController OpRegions.

Regards,

Hans


Hans de Goede (4):
  ACPICA: Add an acpi_early_initialize_objects() helper
  ACPICA: Add \_SB.PC00, \SB.PCI0 to acpi_ns_early_initialize_devices()
  ACPICA: Make address-space-handler install and _REG execution 2
    separate steps
  ACPI: fix ECDT EC probe ordering issues

 drivers/acpi/acpica/acnamesp.h |   2 +
 drivers/acpi/acpica/evxfregn.c |  32 ++++---
 drivers/acpi/acpica/nsinit.c   | 170 ++++++++++++++++++++-------------
 drivers/acpi/acpica/utxfinit.c |  21 ++++
 drivers/acpi/bus.c             |  19 +++-
 drivers/acpi/ec.c              |  38 ++++++--
 drivers/acpi/internal.h        |   1 +
 include/acpi/acpixf.h          |  35 +++++--
 include/acpi/actypes.h         |   5 +-
 9 files changed, 223 insertions(+), 100 deletions(-)