Re: [PATCH v13] i2c: designware: defer probe if child GpioInt controllers are not bound
Andy Shevchenko <[email protected]>
| Newsgroups | org.kernel.vger.linux-i2c,org.kernel.vger.linux-gpio |
|---|---|
| Organization | Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo |
| Message-ID | <[email protected]> |
On Sat, Jul 18, 2026 at 11:13:31AM +0530, Hardik Prakash wrote: > I2C controllers may have child devices with GpioInt resources that > depend on GPIO controllers being fully initialized. If the I2C > controller probes and enumerates children before the referenced GPIO > controller has completed probe, GPIO interrupts may not be properly > configured, leading to device failures. > > On Lenovo Yoga 7 14AGP11, the WACF2200 touchscreen (child of > AMDI0010:02) has a GpioInt resource pointing to GPIO 157 on the > pinctrl-amd controller (AMDI0030:00). When i2c-designware probes > AMDI0010:02 before pinctrl-amd finishes initializing, I2C transactions > fail with lost arbitration errors: > > 0.285952 amd_gpio_probe: registering gpiochip <- GPIO chip visible > 0.287121 amd_gpio_probe: requesting parent IRQ <- probe still running > 0.301454 AMDI0010:02 dw_i2c_plat_probe: start <- races here > 2.348157 lost arbitration > > Add a dependency check that walks ACPI child devices and defers probe > until any referenced GPIO controller is bound. Reviewed-by: Andy Shevchenko <[email protected]> One nit-pick below. No need to resend, hopefully Andi can tweak that whilst applying. ... > +static int check_gpioint_resource(struct acpi_resource *ares, void *data) > +{ > + struct acpi_resource_gpio *agpio; > + struct acpi_device *gpio_adev; > + struct device *gpio_dev; > + acpi_handle handle; > + acpi_status status; > + > + if (!acpi_gpio_get_irq_resource(ares, &agpio)) > + return 1; /* not a GpioInt resource, skip */ > + > + if (!agpio->resource_source.string_length) > + return 1; /* no named controller, skip */ > + > + status = acpi_get_handle(NULL, agpio->resource_source.string_ptr, &handle); > + if (ACPI_FAILURE(status)) > + return 1; > + > + gpio_adev = acpi_fetch_acpi_dev(handle); > + if (!gpio_adev) > + return 1; > + > + struct gpio_device *gdev __free(gpio_device_put) = > + gpio_device_find_by_fwnode(acpi_fwnode_handle(gpio_adev)); > + if (!gdev) > + return -EPROBE_DEFER; /* controller not registered yet: abort walk */ > + > + gpio_dev = gpio_device_to_device(gdev)->parent; > + > + guard(device)(gpio_dev); + blank line here as well. I asked to add blank lines before and after. "...make sure it has a blank lines before and after, so it's visible as a separate entity." > + if (!device_is_bound(gpio_dev)) > + return -EPROBE_DEFER; /* controller not bound yet: abort walk */ > + > + return 1; /* bound, skip adding to resource list, continue walk */ > +} -- With Best Regards, Andy Shevchenko