diff mbox series

[RFC,2/4] ACPICA: Add \_SB.PC00, \SB.PCI0 to acpi_ns_early_initialize_devices()

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

Commit Message

Hans de Goede June 15, 2022, 7:56 p.m. UTC
Since ACPICA commit f005ee6b90d1 / Linux commit 2d3349de8072
("ACPICA: Namespace: Reorder \_SB._INI to make sure it is evaluated
before _REG evaluations") acpi_initialize_objects() calls \_SB._INI
before executing _REG OpRegion methods, because the _REG methods may
rely on initialization done by this _INI method.

In many DSDTs the \_SB.PC00._INI / \_SB.PCI0._INI methods set an OSYS
global variable based on _OSI evaluations.

In some cases there are _REG methods which depend on the OSYS value and
before this change ACPICA would run these _REG methods before running
_SB.PC00._INI / \_SB.PCI0._INI causing issues.

2 examples of problems caused by running _REG methods before these
_INI methods are:

1. on a "Lenovo IdeaPad 5 15ITL05" \_SB.PC00.LPCB.EC0._REG gets
evaluated before \_SB.PC00._INI and that _REG contains:

    If ((OSYS == 0x07DF))
    {
        Local0 = 0x06
    }

    If ((Acquire (LFCM, 0xA000) == Zero))
    {
        OSTY = Local0
        ...

With OSTY being a SystemMemory OpRegion field, due to the _INI running
too late, Local0 stays at 0. Causing OSTY to be set to 0 instead of 6,
which causes the brightness up/down keys to not work:
https://bugzilla.kernel.org/show_bug.cgi?id=214899

2. On a "Lenovo Thinkbook 14-ILL" \\_SB_.PCI0.I2C0._REG gets
evaluated before \_SB.PCI0._INI and that _REG contains:

    If ((OSYS == 0x07DF))
    {
	...
        LNUX = Zero
        TPID = 0x4E
    }
    else
    {
        LNUX = One
        TPID = 0xBB
    }

And then later on the TPID value gets used to decide for which of multiple
devices describing the touchpad _STA should return 0xF and the one which
gets enabled by TPID=0xBB is broken, causing to the touchpad to not work:
https://bugzilla.redhat.com/show_bug.cgi?id=1842039

Fix these issues by adding \_SB.PC00._INI / \_SB.PCI0._INI to the list of
_INI methods to run early (before executing _REG methods).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/acpica/nsinit.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index f5364d44fdb8..db66df28e4fc 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -105,6 +105,10 @@  static acpi_string const acpi_ns_early_init_paths[] = {
 	/* There appears to be a strict order requirement for \_SB._INI,
 	 * which should be evaluated before any _REG evaluations. */
 	"\\_SB",
+	/* \_SB.PC00._INI or \_SB.PCI0.INI may use \_OSI to set an OSYS global
+	 * variable used in _REG methods. */
+	"\\_SB.PC00",
+	"\\_SB.PCI0",
 };
 
 acpi_status acpi_ns_early_initialize_devices(void)
@@ -519,7 +523,7 @@  acpi_ns_find_ini_methods(acpi_handle obj_handle,
 
 static u8 acpi_ns_is_early_init_device(struct acpi_namespace_node *device_node)
 {
-	char path[ACPI_PATH_SEGMENT_LENGTH + 2];
+	char path[ACPI_PATH_SEGMENT_LENGTH * 2 + 2];
 	int i;
 
 	acpi_ns_build_normalized_path(device_node, path, sizeof(path), TRUE);