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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.