diff options
author | Ulrich Huber | 2022-09-21 22:22:53 +0200 |
---|---|---|
committer | Ulrich Huber | 2022-09-21 22:24:35 +0200 |
commit | 778a33aea26bdc9b92b9681980e2081c4899ddb9 (patch) | |
tree | 96bffb72ec28614e08a89141c26dca1da39031f4 /0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch | |
parent | 3b45b83f896a7e2fa1d88201c4f561c9decabc2e (diff) | |
download | aur-778a33aea26bdc9b92b9681980e2081c4899ddb9.tar.gz |
Update to 5.19.9-arch1 with adapted fixes from Philipp Jungkamp
Diffstat (limited to '0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch')
-rw-r--r-- | 0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch b/0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch new file mode 100644 index 000000000000..605f782def8f --- /dev/null +++ b/0002-ACPI-EC-fix-ECDT-probe-ordering-issues.patch @@ -0,0 +1,154 @@ +From 986c9179841b0607302fd5cbf83d5b745cf2a7e6 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Mon, 4 Jul 2022 11:38:10 +0200 +Subject: [PATCH 2/9] ACPI: EC: fix ECDT probe ordering issues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ACPI-2.0 says that the EC OpRegion handler must be available immediately +(like the standard default OpRegion handlers): + +Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... +2. OSPM must make Embedded Controller operation regions, accessed via +the Embedded Controllers described in ECDT, available before executing +any control method. These operation regions may become inaccessible +after OSPM runs _REG(EmbeddedControl, 0)." + +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 . + +Generally speaking _REG methods are executed when the ACPI-device they +are part of has a driver bound to it. Where as _INI methods must be +executed at table load time (according to the spec). The problem here +is that the early acpi_install_address_space_handler() call causes +the _REG handler to run too early. + +To allow fixing this the ACPICA code now allows to split the OpRegion +handler installation and the executing of _REG into 2 separate steps. + +This commit uses this ACPICA functionality to fix the EC probe ordering +by delaying the executing of _REG for ECDT described ECs till the matching +EC device in the DSDT gets parsed and acpi_ec_add() for it gets called. +This moves the calling of _REG for the EC on devices with an ECDT to +the same point in time where it is called on devices without an ECDT table. + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 +Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + drivers/acpi/ec.c | 33 +++++++++++++++++++++++---------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index a1b871a418f8..d2ebe14135bd 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -94,6 +94,7 @@ enum { + EC_FLAGS_QUERY_ENABLED, /* Query is enabled */ + EC_FLAGS_EVENT_HANDLER_INSTALLED, /* Event handler installed */ + EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ ++ EC_FLAGS_EC_REG_CALLED, /* OpReg ACPI _REG method called */ + EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */ + EC_FLAGS_STARTED, /* Driver is started */ + EC_FLAGS_STOPPED, /* Driver is stopped */ +@@ -1459,6 +1460,7 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec) + * ec_install_handlers - Install service callbacks and register query methods. + * @ec: Target EC. + * @device: ACPI device object corresponding to @ec. ++ * @call_reg: If _REG should be called to notify OpRegion availability + * + * Install a handler for the EC address space type unless it has been installed + * already. If @device is not NULL, also look for EC query methods in the +@@ -1471,7 +1473,8 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec) + * -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred, + * or 0 (success) otherwise. + */ +-static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device) ++static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device, ++ bool call_reg) + { + acpi_status status; + +@@ -1479,10 +1482,11 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device) + + if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { + acpi_ec_enter_noirq(ec); +- status = acpi_install_address_space_handler(ec->handle, +- ACPI_ADR_SPACE_EC, +- &acpi_ec_space_handler, +- NULL, ec); ++ status = acpi_install_address_space_handler_flags(ec->handle, ++ ACPI_ADR_SPACE_EC, ++ &acpi_ec_space_handler, ++ NULL, ec, ++ ACPI_NO_EXEC__REG); + if (ACPI_FAILURE(status)) { + acpi_ec_stop(ec, false); + return -ENODEV; +@@ -1490,6 +1494,15 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device) + set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); + } + ++ if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) { ++ acpi_install_address_space_handler_flags(ec->handle, ++ ACPI_ADR_SPACE_EC, ++ &acpi_ec_space_handler, ++ NULL, ec, ++ ACPI_NO_INSTALL_SPACE_HANDLER); ++ set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags); ++ } ++ + if (!device) + return 0; + +@@ -1575,11 +1588,11 @@ static void ec_remove_handlers(struct acpi_ec *ec) + } + } + +-static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device) ++static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool call_reg) + { + int ret; + +- ret = ec_install_handlers(ec, device); ++ ret = ec_install_handlers(ec, device, call_reg); + if (ret) + return ret; + +@@ -1641,7 +1654,7 @@ static int acpi_ec_add(struct acpi_device *device) + } + } + +- ret = acpi_ec_setup(ec, device); ++ ret = acpi_ec_setup(ec, device, true); + if (ret) + goto err; + +@@ -1761,7 +1774,7 @@ void __init acpi_ec_dsdt_probe(void) + * At this point, the GPE is not fully initialized, so do not to + * handle the events. + */ +- ret = acpi_ec_setup(ec, NULL); ++ ret = acpi_ec_setup(ec, NULL, true); + if (ret) { + acpi_ec_free(ec); + return; +@@ -1973,7 +1986,7 @@ void __init acpi_ec_ecdt_probe(void) + * At this point, the namespace is not initialized, so do not find + * the namespace objects, or handle the events. + */ +- ret = acpi_ec_setup(ec, NULL); ++ ret = acpi_ec_setup(ec, NULL, false); + if (ret) { + acpi_ec_free(ec); + goto out; +-- +2.37.1 + |