Re: [PATCH] ACPI: EC: Avoid _REG disconnect on GPIO IRQ defer
From: Rafael J. Wysocki (Intel)
Date: Tue Jul 21 2026 - 09:56:00 EST
On Wed, Jul 15, 2026 at 3:26 AM Zhu Ling <zhuling2709@xxxxxxxxxxxxxx> wrote:
>
> EC event delivery uses either a GPE or, on ACPI reduced hardware
> platforms, a GpioInt resource. The GPE path does not have a provider
> lookup that can defer, but acpi_dev_gpio_irq_get() can return
> -EPROBE_DEFER for the GpioInt path.
>
> ec_install_handlers() currently installs the EC address space handler and
> executes _REG before looking up the GPIO IRQ. If the GPIO lookup then
> defers, acpi_ec_setup() tears the handlers down again. Removing the EC
> address space handler causes ACPICA to execute _REG for disconnect, so
> firmware may observe an EC OpRegion connected -> disconnected transition
> during one failed probe attempt.
>
> This is observable when the namespace EC reuses a boot EC that has already
> installed the EC address space handler. A deferred namespace EC probe can
> disconnect the already usable boot EC OpRegion until a later reprobe
> connects it again. AML that gates EC field accesses on _REG state can
> then return fallback values to other drivers during that window.
>
> Prepare the GPIOInt IRQ before publishing EC OpRegion availability to AML.
> This leaves the GPE path unchanged, keeps non-deferred GPIO lookup errors
> non-fatal as before, and still lets the existing acpi_ec_setup() error
> path clean up real handler installation failures.
>
> Fixes: f6484cadbcaf ("ACPI: EC: clean up handlers on probe failure in acpi_ec_setup()")
> Signed-off-by: Zhu Ling <zhuling2709@xxxxxxxxxxxxxx>
> ---
> drivers/acpi/ec.c | 39 +++++++++++++++++++++++++--------------
> 1 file changed, 25 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
> index 64ad4cfa6208..26550879f43c 100644
> --- a/drivers/acpi/ec.c
> +++ b/drivers/acpi/ec.c
> @@ -1510,6 +1510,23 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
> IRQF_SHARED | IRQF_ONESHOT, "ACPI EC", ec) >= 0;
> }
>
> +static int ec_prepare_gpio_irq(struct acpi_ec *ec, struct acpi_device *device)
> +{
> + int irq;
> +
> + if (!device || ec->gpe >= 0 || ec->irq >= 0)
> + return 0;
> +
> + /* ACPI reduced hardware platforms use a GpioInt from _CRS. */
> + irq = acpi_dev_gpio_irq_get(device, 0);
> + if (irq == -EPROBE_DEFER)
> + return irq;
> + if (irq >= 0)
> + ec->irq = irq;
> +
> + return 0;
> +}
> +
> /**
> * ec_install_handlers - Install service callbacks and register query methods.
> * @ec: Target EC.
> @@ -1524,7 +1541,6 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
> * Return:
> * -ENODEV if the address space handler cannot be installed, which means
> * "unable to handle transactions",
> - * -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,
> @@ -1557,19 +1573,6 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
> if (!device)
> return 0;
>
> - if (ec->gpe < 0) {
> - /* ACPI reduced hardware platforms use a GpioInt from _CRS. */
> - int irq = acpi_dev_gpio_irq_get(device, 0);
> - /*
> - * Bail out right away for deferred probing or complete the
> - * initialization regardless of any other errors.
> - */
> - if (irq == -EPROBE_DEFER)
> - return -EPROBE_DEFER;
> - else if (irq >= 0)
> - ec->irq = irq;
> - }
> -
> if (!test_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags)) {
> /* Find and register all query methods */
> acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
> @@ -1647,6 +1650,14 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool ca
> {
> int ret;
>
> + /*
> + * GPIO IRQ lookup can defer. Do it before publishing the EC
> + * OpRegion to AML to avoid a spurious _REG(disconnect).
> + */
> + ret = ec_prepare_gpio_irq(ec, device);
> + if (ret)
> + return ret;
> +
> /* First EC capable of handling transactions */
> if (!first_ec)
> first_ec = ec;
Applied as 7.3 material, thanks!