* [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11
@ 2026-05-13 6:13 Hardik Prakash
2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Hardik Prakash @ 2026-05-13 6:13 UTC (permalink / raw)
To: linux-gpio, linux-i2c
Cc: linus.walleij, wsa, andriy.shevchenko, Hardik Prakash
The Wacom WACF2200 touchscreen on the Lenovo Yoga 7 14AGP11 (83TD) is
completely non-functional on Linux. The I2C bus (AMDI0010:02) fails with
repeated lost arbitration errors at boot before any driver can probe the
device. The touchscreen works correctly in UEFI and Windows.
Investigation using ACPI _CRS decode and Windows/Linux GPIO register
comparison identified two bugs:
1. GPIO 157 (WACF2200 GpioInt per ACPI _CRS) has INTERRUPT_ENABLE and
INTERRUPT_MASK cleared by amd_gpio_irq_init() and never restored,
preventing the device from signalling the driver. Windows keeps both
bits set after initialisation.
2. i2c_designware probes AMDI0010:02 before pinctrl-amd's probe
completes. A DMI-matched deferral is added to correctly enforce
ordering using device_is_bound() under device_lock().
Patch 1 adds a DMI quirk in pinctrl-amd to restore GPIO 157 interrupt
bits after amd_gpio_irq_init().
Patch 2 adds a probe deferral in i2c-designware-platdrv that correctly
waits for pinctrl-amd to fully complete before AMDI0010:02 is probed,
using acpi_dev_get_first_match_dev() and acpi_get_first_physical_node()
for robust device lookup.
Both patches tested on Lenovo Yoga 7 14AGP11 (83TD), Fedora 44, kernel
7.1.0-rc2+. Touch and stylus fully functional across 4 stable reboots.
v2:
- Patch 2: replace custom HID/UID lookup helpers with
acpi_dev_get_first_match_dev() (Andy Shevchenko)
- Patch 2: use acpi_get_first_physical_node() to get the platform
device for correct device_is_bound() check
- Patch 2: use device_is_bound() under device_lock() with explanatory
comments (Andy Shevchenko)
- Patch 2: fix dev_warn to use dev_name() instead of hardcoded suffix
(Andy Shevchenko)
- Patch 2: fix commit message (removed incorrect "existing" reference)
- Both patches: add Assisted-by tags per coding-assistants.rst
- Patch 1: no functional changes (Acked-by: Andy Shevchenko)
Kernel bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=221494
Related: https://bugzilla.kernel.org/show_bug.cgi?id=221454
drivers/i2c/busses/i2c-designware-platdrv.c | 75 +++++++++++++++++++++
drivers/pinctrl/pinctrl-amd.c | 35 ++++++++++
2 files changed, 110 insertions(+)
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH 1/2] pinctrl-amd: enable IRQ for WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 Hardik Prakash @ 2026-05-13 6:13 ` Hardik Prakash 2026-05-13 7:36 ` Linus Walleij 2026-05-13 17:23 ` Mario Limonciello 2026-05-13 6:13 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash 2026-05-13 17:03 ` [PATCH v2 0/2] Fix WACF2200 touchscreen " Andy Shevchenko 2 siblings, 2 replies; 15+ messages in thread From: Hardik Prakash @ 2026-05-13 6:13 UTC (permalink / raw) To: linux-gpio, linux-i2c Cc: linus.walleij, wsa, andriy.shevchenko, Hardik Prakash On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen controller is wired via I2C2 (AMDI0010:02) with its interrupt on GPIO pin 157 (confirmed via ACPI _CRS GpioInt decode). After amd_gpio_irq_init() clears all GPIO interrupts at boot, pin 157 is never re-enabled, preventing the touchscreen from signalling the driver. Windows keeps GPIO 157 INTERRUPT_ENABLE (bit 11) and INTERRUPT_MASK (bit 12) set after initialisation. Add a DMI quirk to restore these bits after amd_gpio_irq_init() on this hardware. Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> Assisted-by: Claude:claude-sonnet-4-6 Assisted-by: GPT-Codex:gpt-5.2-codex --- drivers/pinctrl/pinctrl-amd.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index e3128b0045d22..64315b0edf2a6 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/bitops.h> #include <linux/pinctrl/pinconf.h> +#include <linux/dmi.h> #include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinmux.h> #include <linux/string_choices.h> @@ -39,6 +40,39 @@ static struct amd_gpio *pinctrl_dev; #endif +static const struct dmi_system_id amd_gpio_quirk_yoga7_14agp11[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83TD"), + DMI_MATCH(DMI_BOARD_NAME, "LNVNB161216"), + }, + }, + { } +}; + +static void amd_gpio_apply_quirks(struct amd_gpio *gpio_dev) +{ + const unsigned int pin = 157; /* WACF2200 GpioInt per ACPI _CRS */ + unsigned long flags; + u32 reg; + + if (!dmi_check_system(amd_gpio_quirk_yoga7_14agp11)) + return; + if (pin >= gpio_dev->gc.ngpio) + return; + + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + reg = readl(gpio_dev->base + pin * 4); + reg |= BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF); + writel(reg, gpio_dev->base + pin * 4); + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); + + dev_info(&gpio_dev->pdev->dev, + "Enabled IRQ for GPIO %u (Yoga 7 14AGP11 touchscreen)\n", + pin); +} + static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset) { unsigned long flags; @@ -1219,6 +1253,7 @@ static int amd_gpio_probe(struct platform_device *pdev) /* Disable and mask interrupts */ amd_gpio_irq_init(gpio_dev); + amd_gpio_apply_quirks(gpio_dev); girq = &gpio_dev->gc.irq; gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip); -- 2.54.0 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 1/2] pinctrl-amd: enable IRQ for WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash @ 2026-05-13 7:36 ` Linus Walleij 2026-05-13 17:23 ` Mario Limonciello 1 sibling, 0 replies; 15+ messages in thread From: Linus Walleij @ 2026-05-13 7:36 UTC (permalink / raw) To: Hardik Prakash Cc: linux-gpio, linux-i2c, linus.walleij, wsa, andriy.shevchenko On Wed, May 13, 2026 at 8:14 AM Hardik Prakash <hardikprakash.official@gmail.com> wrote: > On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen controller > is wired via I2C2 (AMDI0010:02) with its interrupt on GPIO pin 157 > (confirmed via ACPI _CRS GpioInt decode). After amd_gpio_irq_init() > clears all GPIO interrupts at boot, pin 157 is never re-enabled, > preventing the touchscreen from signalling the driver. > > Windows keeps GPIO 157 INTERRUPT_ENABLE (bit 11) and INTERRUPT_MASK > (bit 12) set after initialisation. Add a DMI quirk to restore these > bits after amd_gpio_irq_init() on this hardware. > > Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> > Assisted-by: Claude:claude-sonnet-4-6 > Assisted-by: GPT-Codex:gpt-5.2-codex You forgot to carry over Andy's ACK! I see that the only real change was the addition of the two AI tags so I just added these to the commit already in my tree. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 1/2] pinctrl-amd: enable IRQ for WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash 2026-05-13 7:36 ` Linus Walleij @ 2026-05-13 17:23 ` Mario Limonciello [not found] ` <CANTFpSUr7KWMA5D7wh48f5-Ty9hDo7U7Ydsob32YZuZ83dRiiw@mail.gmail.com> 1 sibling, 1 reply; 15+ messages in thread From: Mario Limonciello @ 2026-05-13 17:23 UTC (permalink / raw) To: Hardik Prakash, linux-gpio, linux-i2c Cc: linus.walleij, wsa, andriy.shevchenko, Natikar, Basavaraj ++ On 5/13/26 01:13, Hardik Prakash wrote: > On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen controller > is wired via I2C2 (AMDI0010:02) with its interrupt on GPIO pin 157 > (confirmed via ACPI _CRS GpioInt decode). After amd_gpio_irq_init() > clears all GPIO interrupts at boot, pin 157 is never re-enabled, > preventing the touchscreen from signalling the driver. > > Windows keeps GPIO 157 INTERRUPT_ENABLE (bit 11) and INTERRUPT_MASK > (bit 12) set after initialisation. Add a DMI quirk to restore these > bits after amd_gpio_irq_init() on this hardware. > > Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> > Assisted-by: Claude:claude-sonnet-4-6 > Assisted-by: GPT-Codex:gpt-5.2-codex > --- > drivers/pinctrl/pinctrl-amd.c | 35 +++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c > index e3128b0045d22..64315b0edf2a6 100644 > --- a/drivers/pinctrl/pinctrl-amd.c > +++ b/drivers/pinctrl/pinctrl-amd.c > @@ -26,6 +26,7 @@ > #include <linux/interrupt.h> > #include <linux/bitops.h> > #include <linux/pinctrl/pinconf.h> > +#include <linux/dmi.h> > #include <linux/pinctrl/pinconf-generic.h> > #include <linux/pinctrl/pinmux.h> > #include <linux/string_choices.h> > @@ -39,6 +40,39 @@ > static struct amd_gpio *pinctrl_dev; > #endif > > +static const struct dmi_system_id amd_gpio_quirk_yoga7_14agp11[] = { > + { > + .matches = { > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), > + DMI_MATCH(DMI_PRODUCT_NAME, "83TD"), > + DMI_MATCH(DMI_BOARD_NAME, "LNVNB161216"), > + }, > + }, > + { } > +}; > + > +static void amd_gpio_apply_quirks(struct amd_gpio *gpio_dev) > +{ > + const unsigned int pin = 157; /* WACF2200 GpioInt per ACPI _CRS */ > + unsigned long flags; > + u32 reg; > + > + if (!dmi_check_system(amd_gpio_quirk_yoga7_14agp11)) > + return; > + if (pin >= gpio_dev->gc.ngpio) > + return; > + > + raw_spin_lock_irqsave(&gpio_dev->lock, flags); > + reg = readl(gpio_dev->base + pin * 4); > + reg |= BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF); > + writel(reg, gpio_dev->base + pin * 4); > + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); > + > + dev_info(&gpio_dev->pdev->dev, > + "Enabled IRQ for GPIO %u (Yoga 7 14AGP11 touchscreen)\n", > + pin); I don't understand. Our design is that the interrupt is disabled initially when driver loads (we don't trust state of the GPIO configuration pre-boot), and then when i2c-hid loads later it is re-enabled via amd_gpio_irq_enable(). Why isn't that flow working on this system? > +} > + > static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset) > { > unsigned long flags; > @@ -1219,6 +1253,7 @@ static int amd_gpio_probe(struct platform_device *pdev) > > /* Disable and mask interrupts */ > amd_gpio_irq_init(gpio_dev); > + amd_gpio_apply_quirks(gpio_dev); > > girq = &gpio_dev->gc.irq; > gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip); ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <CANTFpSUr7KWMA5D7wh48f5-Ty9hDo7U7Ydsob32YZuZ83dRiiw@mail.gmail.com>]
* Re: [PATCH 1/2] pinctrl-amd: enable IRQ for WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 [not found] ` <CANTFpSUr7KWMA5D7wh48f5-Ty9hDo7U7Ydsob32YZuZ83dRiiw@mail.gmail.com> @ 2026-05-14 5:12 ` Hardik Prakash 0 siblings, 0 replies; 15+ messages in thread From: Hardik Prakash @ 2026-05-14 5:12 UTC (permalink / raw) To: Mario Limonciello, linux-gpio, linux-i2c Cc: Andy Shevchenko, wsa, linus.walleij, basavaraj.natikar (Resending with full Cc list — apologies for the missed recipients.) On Wed, May 13, 2026 at 22:53, Mario Limonciello wrote: > I don't understand. Our design is that the interrupt is disabled > initially when driver loads (we don't trust state of the GPIO > configuration pre-boot), and then when i2c-hid loads later it is > re-enabled via amd_gpio_irq_enable(). > > Why isn't that flow working on this system? The flow breaks because i2c-hid never gets to probe. The lost arbitration errors happen on AMDI0010:02 at ~2.3s after boot, before any driver reaches the HID layer. Without the probe ordering fix, i2c_designware probes the bus while pinctrl-amd is still initialising and GPIO 157 (the WACF2200 GpioInt per ACPI _CRS) has its interrupt bits cleared. The bus transaction fails immediately, the device never appears in /sys/bus/hid/devices/, and i2c-hid has nothing to bind to. With patch 1 alone (GPIO IRQ fix), the interrupt is enabled but the probe ordering race still causes arbitration failures. With both patches applied, the bus comes up cleanly and i2c-hid probes successfully. However, see my reply on the 2/2 thread — there may be a deeper cause related to _DSM. Thanks, Hardik On Thu, 14 May 2026 at 10:36, Hardik Prakash <hardikprakash.official@gmail.com> wrote: > > On Wed, May 13, 2026 at 22:53, Mario Limonciello wrote: > > I don't understand. Our design is that the interrupt is disabled > > initially when driver loads (we don't trust state of the GPIO > > configuration pre-boot), and then when i2c-hid loads later it is > > re-enabled via amd_gpio_irq_enable(). > > > > Why isn't that flow working on this system? > > The flow breaks because i2c-hid never gets to probe. The lost > arbitration errors happen on AMDI0010:02 at ~2.3s after boot, before > any driver reaches the HID layer. Without the probe ordering fix, > i2c_designware probes the bus while pinctrl-amd is still initialising > and GPIO 157 (the WACF2200 GpioInt per ACPI _CRS) has its interrupt > bits cleared. The bus transaction fails immediately, the device never > appears in /sys/bus/hid/devices/, and i2c-hid has nothing to bind to. > > With patch 1 alone (GPIO IRQ fix), the interrupt is enabled but the > probe ordering race still causes arbitration failures. With both patches > applied, the bus comes up cleanly and i2c-hid probes successfully. > > However, see my reply on the 2/2 thread — there may be a deeper cause > related to _DSM. > > Thanks, > Hardik > > On Wed, 13 May 2026 at 22:53, Mario Limonciello <superm1@kernel.org> wrote: > > > > ++ > > > > On 5/13/26 01:13, Hardik Prakash wrote: > > > On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen controller > > > is wired via I2C2 (AMDI0010:02) with its interrupt on GPIO pin 157 > > > (confirmed via ACPI _CRS GpioInt decode). After amd_gpio_irq_init() > > > clears all GPIO interrupts at boot, pin 157 is never re-enabled, > > > preventing the touchscreen from signalling the driver. > > > > > > Windows keeps GPIO 157 INTERRUPT_ENABLE (bit 11) and INTERRUPT_MASK > > > (bit 12) set after initialisation. Add a DMI quirk to restore these > > > bits after amd_gpio_irq_init() on this hardware. > > > > > > Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> > > > Assisted-by: Claude:claude-sonnet-4-6 > > > Assisted-by: GPT-Codex:gpt-5.2-codex > > > --- > > > drivers/pinctrl/pinctrl-amd.c | 35 +++++++++++++++++++++++++++++++++++ > > > 1 file changed, 35 insertions(+) > > > > > > diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c > > > index e3128b0045d22..64315b0edf2a6 100644 > > > --- a/drivers/pinctrl/pinctrl-amd.c > > > +++ b/drivers/pinctrl/pinctrl-amd.c > > > @@ -26,6 +26,7 @@ > > > #include <linux/interrupt.h> > > > #include <linux/bitops.h> > > > #include <linux/pinctrl/pinconf.h> > > > +#include <linux/dmi.h> > > > #include <linux/pinctrl/pinconf-generic.h> > > > #include <linux/pinctrl/pinmux.h> > > > #include <linux/string_choices.h> > > > @@ -39,6 +40,39 @@ > > > static struct amd_gpio *pinctrl_dev; > > > #endif > > > > > > +static const struct dmi_system_id amd_gpio_quirk_yoga7_14agp11[] = { > > > + { > > > + .matches = { > > > + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), > > > + DMI_MATCH(DMI_PRODUCT_NAME, "83TD"), > > > + DMI_MATCH(DMI_BOARD_NAME, "LNVNB161216"), > > > + }, > > > + }, > > > + { } > > > +}; > > > + > > > +static void amd_gpio_apply_quirks(struct amd_gpio *gpio_dev) > > > +{ > > > + const unsigned int pin = 157; /* WACF2200 GpioInt per ACPI _CRS */ > > > + unsigned long flags; > > > + u32 reg; > > > + > > > + if (!dmi_check_system(amd_gpio_quirk_yoga7_14agp11)) > > > + return; > > > + if (pin >= gpio_dev->gc.ngpio) > > > + return; > > > + > > > + raw_spin_lock_irqsave(&gpio_dev->lock, flags); > > > + reg = readl(gpio_dev->base + pin * 4); > > > + reg |= BIT(INTERRUPT_ENABLE_OFF) | BIT(INTERRUPT_MASK_OFF); > > > + writel(reg, gpio_dev->base + pin * 4); > > > + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); > > > + > > > + dev_info(&gpio_dev->pdev->dev, > > > + "Enabled IRQ for GPIO %u (Yoga 7 14AGP11 touchscreen)\n", > > > + pin); > > > > I don't understand. Our design is that the interrupt is disabled > > initially when driver loads (we don't trust state of the GPIO > > configuration pre-boot), and then when i2c-hid loads later it is > > re-enabled via amd_gpio_irq_enable(). > > > > Why isn't that flow working on this system? > > > > > +} > > > + > > > static int amd_gpio_get_direction(struct gpio_chip *gc, unsigned offset) > > > { > > > unsigned long flags; > > > @@ -1219,6 +1253,7 @@ static int amd_gpio_probe(struct platform_device *pdev) > > > > > > /* Disable and mask interrupts */ > > > amd_gpio_irq_init(gpio_dev); > > > + amd_gpio_apply_quirks(gpio_dev); > > > > > > girq = &gpio_dev->gc.irq; > > > gpio_irq_chip_set_chip(girq, &amd_gpio_irqchip); > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 Hardik Prakash 2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash @ 2026-05-13 6:13 ` Hardik Prakash 2026-05-13 17:12 ` Andy Shevchenko 2026-05-13 17:03 ` [PATCH v2 0/2] Fix WACF2200 touchscreen " Andy Shevchenko 2 siblings, 1 reply; 15+ messages in thread From: Hardik Prakash @ 2026-05-13 6:13 UTC (permalink / raw) To: linux-gpio, linux-i2c Cc: linus.walleij, wsa, andriy.shevchenko, Hardik Prakash On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen fails with lost arbitration errors on AMDI0010:02 at boot. The root cause is a probe ordering issue: i2c_designware probes AMDI0010:02 before pinctrl-amd has finished initialising, so the GPIO 157 interrupt needed by the touchscreen is not yet enabled. Add a DMI-matched deferral in dw_i2c_plat_probe() that uses device_is_bound() under device_lock() to correctly wait until pinctrl-amd's probe has fully completed. Use acpi_dev_get_first_match_dev() for robust HID/UID-based GPIO controller lookup instead of string name matching. Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> Assisted-by: Claude:claude-sonnet-4-6 Assisted-by: GPT-Codex:gpt-5.2-codex --- drivers/i2c/busses/i2c-designware-platdrv.c | 75 +++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 3351c4a9ef118..35fa4bcafc7ad 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -8,6 +8,7 @@ * Copyright (C) 2007 MontaVista Software Inc. * Copyright (C) 2009 Provigent Ltd. */ +#include <linux/acpi.h> #include <linux/clk-provider.h> #include <linux/clk.h> #include <linux/delay.h> @@ -86,6 +87,76 @@ static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { { } /* terminate list */ }; +static const struct dmi_system_id dw_i2c_amd_gpio_defer_dmi[] = { + { + .ident = "Lenovo Yoga 7 14AGP11", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83TD"), + DMI_MATCH(DMI_BOARD_NAME, "LNVNB161216"), + }, + }, + { } /* terminate list */ +}; + +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) +{ + struct acpi_device *adev = ACPI_COMPANION(device); + + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) + return false; + if (!adev) + return false; + + return acpi_dev_hid_uid_match(adev, "AMDI0010", "2"); +} + +static int dw_i2c_defer_for_amd_gpio(struct device *device) +{ + struct acpi_device *gpio_adev; + struct device *gpio_dev; + + if (!dw_i2c_needs_amd_gpio_dep(device)) + return 0; + + /* + * Find the AMD GPIO controller by HID/UID and get its physical + * platform device. We need the platform device (not the ACPI device) + * because that is what gets bound by the amd_gpio driver. + */ + gpio_adev = acpi_dev_get_first_match_dev("AMDI0030", "0", -1); + if (!gpio_adev) + return -EPROBE_DEFER; + + gpio_dev = acpi_get_first_physical_node(gpio_adev); + acpi_dev_put(gpio_adev); + if (!gpio_dev) + return -EPROBE_DEFER; + + /* + * Check that amd_gpio probe has fully completed, not just that the + * driver pointer is set. The driver pointer is assigned before probe + * finishes, so checking it would allow i2c_designware to probe before + * the GPIO IRQ quirk in amd_gpio_probe() has run. + */ + device_lock(gpio_dev); + if (!device_is_bound(gpio_dev)) { + device_unlock(gpio_dev); + return -EPROBE_DEFER; + } + device_unlock(gpio_dev); + + /* + * Create a device link so the driver core enforces probe/remove + * ordering between this I2C controller and the GPIO controller. + */ + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) + dev_warn(device, "failed to add device link to %s\n", + dev_name(gpio_dev)); + + return 0; +} + static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = { #ifdef CONFIG_I2C_DESIGNWARE_BAYTRAIL { @@ -138,6 +209,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) struct dw_i2c_dev *dev; int irq, ret; + ret = dw_i2c_defer_for_amd_gpio(device); + if (ret) + return ret; + irq = platform_get_irq_optional(pdev, 0); if (irq == -ENXIO) flags |= ACCESS_POLLING; -- 2.54.0 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash @ 2026-05-13 17:12 ` Andy Shevchenko 2026-05-13 17:28 ` Mario Limonciello 0 siblings, 1 reply; 15+ messages in thread From: Andy Shevchenko @ 2026-05-13 17:12 UTC (permalink / raw) To: Hardik Prakash, Mario Limonciello, Bartosz Golaszewski Cc: linux-gpio, linux-i2c, linus.walleij, wsa Please, Cc AMD people on the AMD related stuff. +Cc: Mario +Cc: Bart (the GPIO enumeration and checks, smells like it might be done differently). On Wed, May 13, 2026 at 11:43:38AM +0530, Hardik Prakash wrote: > On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen fails with > lost arbitration errors on AMDI0010:02 at boot. The root cause is a > probe ordering issue: i2c_designware probes AMDI0010:02 before > pinctrl-amd has finished initialising, so the GPIO 157 interrupt > needed by the touchscreen is not yet enabled. > > Add a DMI-matched deferral in dw_i2c_plat_probe() that uses > device_is_bound() under device_lock() to correctly wait until > pinctrl-amd's probe has fully completed. Use acpi_dev_get_first_match_dev() > for robust HID/UID-based GPIO controller lookup instead of string > name matching. ... > +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) > +{ > + struct acpi_device *adev = ACPI_COMPANION(device); Split hard-to-maintain definition and assignment that's going to be validated. > + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > + return false; > + if (!adev) > + return false; struct acpi_device *adev; if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) return false; adev = ACPI_COMPANION(device); if (!adev) return false; > + return acpi_dev_hid_uid_match(adev, "AMDI0010", "2"); > +} ... > +static int dw_i2c_defer_for_amd_gpio(struct device *device) > +{ > + struct acpi_device *gpio_adev; > + struct device *gpio_dev; > + > + if (!dw_i2c_needs_amd_gpio_dep(device)) > + return 0; > + > + /* > + * Find the AMD GPIO controller by HID/UID and get its physical > + * platform device. We need the platform device (not the ACPI device) > + * because that is what gets bound by the amd_gpio driver. > + */ > + gpio_adev = acpi_dev_get_first_match_dev("AMDI0030", "0", -1); > + if (!gpio_adev) > + return -EPROBE_DEFER; Hmm... This is interesting case, smells like something similar to what we had with x86 Android quirk driver. Cc'ed to Bart to briefly look at this. > + gpio_dev = acpi_get_first_physical_node(gpio_adev); > + acpi_dev_put(gpio_adev); > + if (!gpio_dev) > + return -EPROBE_DEFER; > + > + /* > + * Check that amd_gpio probe has fully completed, not just that the > + * driver pointer is set. The driver pointer is assigned before probe > + * finishes, so checking it would allow i2c_designware to probe before > + * the GPIO IRQ quirk in amd_gpio_probe() has run. > + */ > + device_lock(gpio_dev); > + if (!device_is_bound(gpio_dev)) { > + device_unlock(gpio_dev); > + return -EPROBE_DEFER; > + } > + device_unlock(gpio_dev); > + > + /* > + * Create a device link so the driver core enforces probe/remove > + * ordering between this I2C controller and the GPIO controller. > + */ > + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) > + dev_warn(device, "failed to add device link to %s\n", > + dev_name(gpio_dev)); > + > + return 0; > +} -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-13 17:12 ` Andy Shevchenko @ 2026-05-13 17:28 ` Mario Limonciello [not found] ` <CANTFpSU=94RuX1uFf4UitRyzLPvu=cTF_S5khjjJNQUU1T_PtA@mail.gmail.com> 0 siblings, 1 reply; 15+ messages in thread From: Mario Limonciello @ 2026-05-13 17:28 UTC (permalink / raw) To: Andy Shevchenko, Hardik Prakash, Bartosz Golaszewski Cc: linux-gpio, linux-i2c, linus.walleij, wsa, Natikar, Basavaraj ++ On 5/13/26 12:12, Andy Shevchenko wrote: > Please, Cc AMD people on the AMD related stuff. > +Cc: Mario > > +Cc: Bart > (the GPIO enumeration and checks, smells like it might be done differently). Yeah; I tend to think doing this with a quirk is hiding a bug. Are you sure this isn't a case of two masters on the bus? [ 2.286838] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.286887] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.286923] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.286964] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.287521] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.287569] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.287616] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration [ 2.287658] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost arbitration I saw something really similar on a Dell platform last year; but around S4. It ended up being a situation that the EC had way to act as I2C master and until the right method from I2C-HID was called it thought it was still I2C master. https://git.kernel.org/torvalds/c/7d62beb102d6f Could this be something similar that really calling the _DSM is the missing link? > > On Wed, May 13, 2026 at 11:43:38AM +0530, Hardik Prakash wrote: >> On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen fails with >> lost arbitration errors on AMDI0010:02 at boot. The root cause is a >> probe ordering issue: i2c_designware probes AMDI0010:02 before >> pinctrl-amd has finished initialising, so the GPIO 157 interrupt >> needed by the touchscreen is not yet enabled. >> >> Add a DMI-matched deferral in dw_i2c_plat_probe() that uses >> device_is_bound() under device_lock() to correctly wait until >> pinctrl-amd's probe has fully completed. Use acpi_dev_get_first_match_dev() >> for robust HID/UID-based GPIO controller lookup instead of string >> name matching. > > ... > >> +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) >> +{ >> + struct acpi_device *adev = ACPI_COMPANION(device); > > Split hard-to-maintain definition and assignment that's going to be validated. > >> + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) >> + return false; >> + if (!adev) >> + return false; > > struct acpi_device *adev; > > if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > return false; > > adev = ACPI_COMPANION(device); > if (!adev) > return false; > >> + return acpi_dev_hid_uid_match(adev, "AMDI0010", "2"); >> +} > > ... > >> +static int dw_i2c_defer_for_amd_gpio(struct device *device) >> +{ >> + struct acpi_device *gpio_adev; >> + struct device *gpio_dev; >> + >> + if (!dw_i2c_needs_amd_gpio_dep(device)) >> + return 0; >> + >> + /* >> + * Find the AMD GPIO controller by HID/UID and get its physical >> + * platform device. We need the platform device (not the ACPI device) >> + * because that is what gets bound by the amd_gpio driver. >> + */ >> + gpio_adev = acpi_dev_get_first_match_dev("AMDI0030", "0", -1); >> + if (!gpio_adev) >> + return -EPROBE_DEFER; > > Hmm... This is interesting case, smells like something similar to what we had > with x86 Android quirk driver. Cc'ed to Bart to briefly look at this. > >> + gpio_dev = acpi_get_first_physical_node(gpio_adev); >> + acpi_dev_put(gpio_adev); >> + if (!gpio_dev) >> + return -EPROBE_DEFER; >> + >> + /* >> + * Check that amd_gpio probe has fully completed, not just that the >> + * driver pointer is set. The driver pointer is assigned before probe >> + * finishes, so checking it would allow i2c_designware to probe before >> + * the GPIO IRQ quirk in amd_gpio_probe() has run. >> + */ >> + device_lock(gpio_dev); >> + if (!device_is_bound(gpio_dev)) { >> + device_unlock(gpio_dev); >> + return -EPROBE_DEFER; >> + } >> + device_unlock(gpio_dev); >> + >> + /* >> + * Create a device link so the driver core enforces probe/remove >> + * ordering between this I2C controller and the GPIO controller. >> + */ >> + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) >> + dev_warn(device, "failed to add device link to %s\n", >> + dev_name(gpio_dev)); >> + >> + return 0; >> +} > ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <CANTFpSU=94RuX1uFf4UitRyzLPvu=cTF_S5khjjJNQUU1T_PtA@mail.gmail.com>]
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 [not found] ` <CANTFpSU=94RuX1uFf4UitRyzLPvu=cTF_S5khjjJNQUU1T_PtA@mail.gmail.com> @ 2026-05-14 5:14 ` Hardik Prakash 2026-05-14 5:43 ` Hardik Prakash 0 siblings, 1 reply; 15+ messages in thread From: Hardik Prakash @ 2026-05-14 5:14 UTC (permalink / raw) To: Mario Limonciello, Andy Shevchenko, brgl Cc: linux-gpio, linux-i2c, linus.walleij, wsa, basavaraj.natikar (Resending with full Cc list — apologies for the missed recipients.) On Wed, May 13, 2026 at 22:58, Mario Limonciello wrote: > Yeah; I tend to think doing this with a quirk is hiding a bug. > > Are you sure this isn't a case of two masters on the bus? I looked into this after your email. The DSDT for TPNL (WACF2200) does have a _DSM with UUID 3cdff6f7-4267-4555-ad05-b30a3d8938de (HID I2C Device). So yes — this could be the same mechanism you saw on Dell. > Could this be something similar that really calling the _DSM is the > missing link? Possibly. With my current patches applied, the probe ordering fix ensures i2c_designware initialises AMDI0010:02 cleanly, i2c-hid subsequently probes, and presumably calls the _DSM at that point — which may be what finally releases the bus. Without the patches, i2c-hid never gets that far. The question I can't answer yet is whether the _DSM needs to be called *before* the first I2C bus transaction attempt, rather than at i2c-hid probe time. If the firmware is acting as I2C master until the _DSM is called, then the arbitration errors at 2.3s would be explained entirely by the missing _DSM call, independent of the GPIO IRQ state. I'm investigating the _DSM content further. If you believe the correct fix is an earlier _DSM call (similar to what 7d62beb did for S4), I'm happy to test a patch for that approach and report back. Thanks, Hardik On Thu, 14 May 2026 at 10:37, Hardik Prakash <hardikprakash.official@gmail.com> wrote: > > On Wed, May 13, 2026 at 22:58, Mario Limonciello wrote: > > Yeah; I tend to think doing this with a quirk is hiding a bug. > > > > Are you sure this isn't a case of two masters on the bus? > > I looked into this after your email. The DSDT for TPNL (WACF2200) does > have a _DSM with UUID 3cdff6f7-4267-4555-ad05-b30a3d8938de (HID I2C > Device). So yes — this could be the same mechanism you saw on Dell. > > > Could this be something similar that really calling the _DSM is the > > missing link? > > Possibly. With my current patches applied, the probe ordering fix > ensures i2c_designware initialises AMDI0010:02 cleanly, i2c-hid > subsequently probes, and presumably calls the _DSM at that point — > which may be what finally releases the bus. Without the patches, > i2c-hid never gets that far. > > The question I can't answer yet is whether the _DSM needs to be called > *before* the first I2C bus transaction attempt, rather than at i2c-hid > probe time. If the firmware is acting as I2C master until the _DSM is > called, then the arbitration errors at 2.3s would be explained entirely > by the missing _DSM call, independent of the GPIO IRQ state. > > I'm investigating the _DSM content further. If you believe the correct > fix is an earlier _DSM call (similar to what 7d62beb did for S4), I'm > happy to test a patch for that approach and report back. > > Thanks, > Hardik > > On Wed, 13 May 2026 at 22:58, Mario Limonciello <superm1@kernel.org> wrote: > > > > ++ > > > > On 5/13/26 12:12, Andy Shevchenko wrote: > > > Please, Cc AMD people on the AMD related stuff. > > > +Cc: Mario > > > > > > +Cc: Bart > > > (the GPIO enumeration and checks, smells like it might be done differently). > > > > Yeah; I tend to think doing this with a quirk is hiding a bug. > > > > Are you sure this isn't a case of two masters on the bus? > > > > [ 2.286838] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.286887] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.286923] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.286964] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.287521] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.287569] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.287616] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > [ 2.287658] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > arbitration > > > > I saw something really similar on a Dell platform last year; but around S4. > > > > It ended up being a situation that the EC had way to act as I2C master > > and until the right method from I2C-HID was called it thought it was > > still I2C master. > > > > https://git.kernel.org/torvalds/c/7d62beb102d6f > > > > Could this be something similar that really calling the _DSM is the > > missing link? > > > > > > > > On Wed, May 13, 2026 at 11:43:38AM +0530, Hardik Prakash wrote: > > >> On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen fails with > > >> lost arbitration errors on AMDI0010:02 at boot. The root cause is a > > >> probe ordering issue: i2c_designware probes AMDI0010:02 before > > >> pinctrl-amd has finished initialising, so the GPIO 157 interrupt > > >> needed by the touchscreen is not yet enabled. > > >> > > >> Add a DMI-matched deferral in dw_i2c_plat_probe() that uses > > >> device_is_bound() under device_lock() to correctly wait until > > >> pinctrl-amd's probe has fully completed. Use acpi_dev_get_first_match_dev() > > >> for robust HID/UID-based GPIO controller lookup instead of string > > >> name matching. > > > > > > ... > > > > > >> +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) > > >> +{ > > >> + struct acpi_device *adev = ACPI_COMPANION(device); > > > > > > Split hard-to-maintain definition and assignment that's going to be validated. > > > > > >> + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > > >> + return false; > > >> + if (!adev) > > >> + return false; > > > > > > struct acpi_device *adev; > > > > > > if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > > > return false; > > > > > > adev = ACPI_COMPANION(device); > > > if (!adev) > > > return false; > > > > > >> + return acpi_dev_hid_uid_match(adev, "AMDI0010", "2"); > > >> +} > > > > > > ... > > > > > >> +static int dw_i2c_defer_for_amd_gpio(struct device *device) > > >> +{ > > >> + struct acpi_device *gpio_adev; > > >> + struct device *gpio_dev; > > >> + > > >> + if (!dw_i2c_needs_amd_gpio_dep(device)) > > >> + return 0; > > >> + > > >> + /* > > >> + * Find the AMD GPIO controller by HID/UID and get its physical > > >> + * platform device. We need the platform device (not the ACPI device) > > >> + * because that is what gets bound by the amd_gpio driver. > > >> + */ > > >> + gpio_adev = acpi_dev_get_first_match_dev("AMDI0030", "0", -1); > > >> + if (!gpio_adev) > > >> + return -EPROBE_DEFER; > > > > > > Hmm... This is interesting case, smells like something similar to what we had > > > with x86 Android quirk driver. Cc'ed to Bart to briefly look at this. > > > > > >> + gpio_dev = acpi_get_first_physical_node(gpio_adev); > > >> + acpi_dev_put(gpio_adev); > > >> + if (!gpio_dev) > > >> + return -EPROBE_DEFER; > > >> + > > >> + /* > > >> + * Check that amd_gpio probe has fully completed, not just that the > > >> + * driver pointer is set. The driver pointer is assigned before probe > > >> + * finishes, so checking it would allow i2c_designware to probe before > > >> + * the GPIO IRQ quirk in amd_gpio_probe() has run. > > >> + */ > > >> + device_lock(gpio_dev); > > >> + if (!device_is_bound(gpio_dev)) { > > >> + device_unlock(gpio_dev); > > >> + return -EPROBE_DEFER; > > >> + } > > >> + device_unlock(gpio_dev); > > >> + > > >> + /* > > >> + * Create a device link so the driver core enforces probe/remove > > >> + * ordering between this I2C controller and the GPIO controller. > > >> + */ > > >> + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) > > >> + dev_warn(device, "failed to add device link to %s\n", > > >> + dev_name(gpio_dev)); > > >> + > > >> + return 0; > > >> +} > > > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-14 5:14 ` Hardik Prakash @ 2026-05-14 5:43 ` Hardik Prakash 0 siblings, 0 replies; 15+ messages in thread From: Hardik Prakash @ 2026-05-14 5:43 UTC (permalink / raw) To: Mario Limonciello, Andy Shevchenko, brgl Cc: linux-gpio, linux-i2c, linus.walleij, wsa, basavaraj.natikar On Wed, May 13, 2026 at 22:58, Mario Limonciello wrote: > Could this be something similar that really calling the _DSM is the > missing link? Correction to my previous reply — I've now disassembled the DSDT and looked at the _DSM content directly. TPNL's _DSM (UUID 3cdff6f7-4267-4555-ad05-b30a3d8938de): Function 0 (revision 1): returns 0x03 (functions 0 and 1 supported) Function 1: returns integer 1 (HID descriptor address) All other functions: return 0 There are no side effects — no power sequencing, no GPIO operations, no bus ownership transfer. It is a pure query method that returns a constant HID descriptor address. This makes the dual-master scenario less likely for this hardware than it was for the Dell case. Based on the DSDT, I don't see evidence that the firmware is acting as a secondary I2C master, or that calling the _DSM earlier would change the bus arbitration behaviour. The arbitration errors on this system appear to be explained by the GPIO IRQ not being enabled (patch 1) and the probe ordering race (patch 2). That said, I could be wrong — if you see something in the DSDT or elsewhere that suggests otherwise, I'm happy to test a different approach. Thanks, Hardik On Thu, 14 May 2026 at 10:44, Hardik Prakash <hardikprakash.official@gmail.com> wrote: > > (Resending with full Cc list — apologies for the missed recipients.) > > On Wed, May 13, 2026 at 22:58, Mario Limonciello wrote: > > Yeah; I tend to think doing this with a quirk is hiding a bug. > > > > Are you sure this isn't a case of two masters on the bus? > > I looked into this after your email. The DSDT for TPNL (WACF2200) does > have a _DSM with UUID 3cdff6f7-4267-4555-ad05-b30a3d8938de (HID I2C > Device). So yes — this could be the same mechanism you saw on Dell. > > > Could this be something similar that really calling the _DSM is the > > missing link? > > Possibly. With my current patches applied, the probe ordering fix > ensures i2c_designware initialises AMDI0010:02 cleanly, i2c-hid > subsequently probes, and presumably calls the _DSM at that point — > which may be what finally releases the bus. Without the patches, > i2c-hid never gets that far. > > The question I can't answer yet is whether the _DSM needs to be called > *before* the first I2C bus transaction attempt, rather than at i2c-hid > probe time. If the firmware is acting as I2C master until the _DSM is > called, then the arbitration errors at 2.3s would be explained entirely > by the missing _DSM call, independent of the GPIO IRQ state. > > I'm investigating the _DSM content further. If you believe the correct > fix is an earlier _DSM call (similar to what 7d62beb did for S4), I'm > happy to test a patch for that approach and report back. > > Thanks, > Hardik > > On Thu, 14 May 2026 at 10:37, Hardik Prakash > <hardikprakash.official@gmail.com> wrote: > > > > On Wed, May 13, 2026 at 22:58, Mario Limonciello wrote: > > > Yeah; I tend to think doing this with a quirk is hiding a bug. > > > > > > Are you sure this isn't a case of two masters on the bus? > > > > I looked into this after your email. The DSDT for TPNL (WACF2200) does > > have a _DSM with UUID 3cdff6f7-4267-4555-ad05-b30a3d8938de (HID I2C > > Device). So yes — this could be the same mechanism you saw on Dell. > > > > > Could this be something similar that really calling the _DSM is the > > > missing link? > > > > Possibly. With my current patches applied, the probe ordering fix > > ensures i2c_designware initialises AMDI0010:02 cleanly, i2c-hid > > subsequently probes, and presumably calls the _DSM at that point — > > which may be what finally releases the bus. Without the patches, > > i2c-hid never gets that far. > > > > The question I can't answer yet is whether the _DSM needs to be called > > *before* the first I2C bus transaction attempt, rather than at i2c-hid > > probe time. If the firmware is acting as I2C master until the _DSM is > > called, then the arbitration errors at 2.3s would be explained entirely > > by the missing _DSM call, independent of the GPIO IRQ state. > > > > I'm investigating the _DSM content further. If you believe the correct > > fix is an earlier _DSM call (similar to what 7d62beb did for S4), I'm > > happy to test a patch for that approach and report back. > > > > Thanks, > > Hardik > > > > On Wed, 13 May 2026 at 22:58, Mario Limonciello <superm1@kernel.org> wrote: > > > > > > ++ > > > > > > On 5/13/26 12:12, Andy Shevchenko wrote: > > > > Please, Cc AMD people on the AMD related stuff. > > > > +Cc: Mario > > > > > > > > +Cc: Bart > > > > (the GPIO enumeration and checks, smells like it might be done differently). > > > > > > Yeah; I tend to think doing this with a quirk is hiding a bug. > > > > > > Are you sure this isn't a case of two masters on the bus? > > > > > > [ 2.286838] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.286887] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.286923] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.286964] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.287521] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.287569] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.287616] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > [ 2.287658] i2c_designware AMDI0010:02: i2c_dw_handle_tx_abort: lost > > > arbitration > > > > > > I saw something really similar on a Dell platform last year; but around S4. > > > > > > It ended up being a situation that the EC had way to act as I2C master > > > and until the right method from I2C-HID was called it thought it was > > > still I2C master. > > > > > > https://git.kernel.org/torvalds/c/7d62beb102d6f > > > > > > Could this be something similar that really calling the _DSM is the > > > missing link? > > > > > > > > > > > On Wed, May 13, 2026 at 11:43:38AM +0530, Hardik Prakash wrote: > > > >> On Lenovo Yoga 7 14AGP11 (83TD), the WACF2200 touchscreen fails with > > > >> lost arbitration errors on AMDI0010:02 at boot. The root cause is a > > > >> probe ordering issue: i2c_designware probes AMDI0010:02 before > > > >> pinctrl-amd has finished initialising, so the GPIO 157 interrupt > > > >> needed by the touchscreen is not yet enabled. > > > >> > > > >> Add a DMI-matched deferral in dw_i2c_plat_probe() that uses > > > >> device_is_bound() under device_lock() to correctly wait until > > > >> pinctrl-amd's probe has fully completed. Use acpi_dev_get_first_match_dev() > > > >> for robust HID/UID-based GPIO controller lookup instead of string > > > >> name matching. > > > > > > > > ... > > > > > > > >> +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) > > > >> +{ > > > >> + struct acpi_device *adev = ACPI_COMPANION(device); > > > > > > > > Split hard-to-maintain definition and assignment that's going to be validated. > > > > > > > >> + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > > > >> + return false; > > > >> + if (!adev) > > > >> + return false; > > > > > > > > struct acpi_device *adev; > > > > > > > > if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > > > > return false; > > > > > > > > adev = ACPI_COMPANION(device); > > > > if (!adev) > > > > return false; > > > > > > > >> + return acpi_dev_hid_uid_match(adev, "AMDI0010", "2"); > > > >> +} > > > > > > > > ... > > > > > > > >> +static int dw_i2c_defer_for_amd_gpio(struct device *device) > > > >> +{ > > > >> + struct acpi_device *gpio_adev; > > > >> + struct device *gpio_dev; > > > >> + > > > >> + if (!dw_i2c_needs_amd_gpio_dep(device)) > > > >> + return 0; > > > >> + > > > >> + /* > > > >> + * Find the AMD GPIO controller by HID/UID and get its physical > > > >> + * platform device. We need the platform device (not the ACPI device) > > > >> + * because that is what gets bound by the amd_gpio driver. > > > >> + */ > > > >> + gpio_adev = acpi_dev_get_first_match_dev("AMDI0030", "0", -1); > > > >> + if (!gpio_adev) > > > >> + return -EPROBE_DEFER; > > > > > > > > Hmm... This is interesting case, smells like something similar to what we had > > > > with x86 Android quirk driver. Cc'ed to Bart to briefly look at this. > > > > > > > >> + gpio_dev = acpi_get_first_physical_node(gpio_adev); > > > >> + acpi_dev_put(gpio_adev); > > > >> + if (!gpio_dev) > > > >> + return -EPROBE_DEFER; > > > >> + > > > >> + /* > > > >> + * Check that amd_gpio probe has fully completed, not just that the > > > >> + * driver pointer is set. The driver pointer is assigned before probe > > > >> + * finishes, so checking it would allow i2c_designware to probe before > > > >> + * the GPIO IRQ quirk in amd_gpio_probe() has run. > > > >> + */ > > > >> + device_lock(gpio_dev); > > > >> + if (!device_is_bound(gpio_dev)) { > > > >> + device_unlock(gpio_dev); > > > >> + return -EPROBE_DEFER; > > > >> + } > > > >> + device_unlock(gpio_dev); > > > >> + > > > >> + /* > > > >> + * Create a device link so the driver core enforces probe/remove > > > >> + * ordering between this I2C controller and the GPIO controller. > > > >> + */ > > > >> + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) > > > >> + dev_warn(device, "failed to add device link to %s\n", > > > >> + dev_name(gpio_dev)); > > > >> + > > > >> + return 0; > > > >> +} > > > > > > > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 2026-05-13 6:13 [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 Hardik Prakash 2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash 2026-05-13 6:13 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash @ 2026-05-13 17:03 ` Andy Shevchenko 2 siblings, 0 replies; 15+ messages in thread From: Andy Shevchenko @ 2026-05-13 17:03 UTC (permalink / raw) To: Hardik Prakash; +Cc: linux-gpio, linux-i2c, linus.walleij, wsa On Wed, May 13, 2026 at 11:43:36AM +0530, Hardik Prakash wrote: > The Wacom WACF2200 touchscreen on the Lenovo Yoga 7 14AGP11 (83TD) is > completely non-functional on Linux. The I2C bus (AMDI0010:02) fails with > repeated lost arbitration errors at boot before any driver can probe the > device. The touchscreen works correctly in UEFI and Windows. > > Investigation using ACPI _CRS decode and Windows/Linux GPIO register > comparison identified two bugs: > > 1. GPIO 157 (WACF2200 GpioInt per ACPI _CRS) has INTERRUPT_ENABLE and > INTERRUPT_MASK cleared by amd_gpio_irq_init() and never restored, > preventing the device from signalling the driver. Windows keeps both > bits set after initialisation. > > 2. i2c_designware probes AMDI0010:02 before pinctrl-amd's probe > completes. A DMI-matched deferral is added to correctly enforce > ordering using device_is_bound() under device_lock(). > > Patch 1 adds a DMI quirk in pinctrl-amd to restore GPIO 157 interrupt > bits after amd_gpio_irq_init(). > > Patch 2 adds a probe deferral in i2c-designware-platdrv that correctly > waits for pinctrl-amd to fully complete before AMDI0010:02 is probed, > using acpi_dev_get_first_match_dev() and acpi_get_first_physical_node() > for robust device lookup. > > Both patches tested on Lenovo Yoga 7 14AGP11 (83TD), Fedora 44, kernel > 7.1.0-rc2+. Touch and stylus fully functional across 4 stable reboots. The Subject in the patches misses versioning, use git format-patch -v<N> --cover-letter ... where <N> is the version, to get proper format in the Subject. Also link to the bugzilla makes sense as BugLink tag in the patch(es): BugLink: $URL Or simple Link. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11
@ 2026-05-12 7:31 Hardik Prakash
2026-05-12 7:31 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash
0 siblings, 1 reply; 15+ messages in thread
From: Hardik Prakash @ 2026-05-12 7:31 UTC (permalink / raw)
To: linux-gpio, linux-i2c; +Cc: linus.walleij, wsa, Hardik Prakash
The Wacom WACF2200 touchscreen on the Lenovo Yoga 7 14AGP11 (83TD) is
completely non-functional on Linux. The I2C bus (AMDI0010:02) fails with
repeated lost arbitration errors at boot before any driver can probe the
device. The touchscreen works correctly in UEFI and Windows.
Investigation using ACPI _CRS decode and Windows/Linux GPIO register
comparison identified two bugs:
1. GPIO 157 (WACF2200 GpioInt per ACPI _CRS) has INTERRUPT_ENABLE and
INTERRUPT_MASK cleared by amd_gpio_irq_init() and never restored,
preventing the device from signalling the driver. Windows keeps both
bits set after initialisation.
2. i2c_designware probes AMDI0010:02 before pinctrl-amd's probe
completes. The existing dw_i2c_amd_gpio_defer_dmi quirk for this
hardware checks gpio_dev->driver which is set before probe finishes,
so the deferral does not actually enforce ordering.
Patch 1 adds a DMI quirk in pinctrl-amd to restore GPIO 157 interrupt
bits after amd_gpio_irq_init().
Patch 2 fixes the existing broken deferral in i2c-designware-platdrv to
use device_is_bound() under device_lock(), which correctly waits for
pinctrl-amd probe to complete before AMDI0010:02 is probed.
Both patches tested on Lenovo Yoga 7 14AGP11 (83TD), Fedora 44, kernel
7.1.0-rc2+. Touch and stylus fully functional after applying both patches.
Kernel bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=221494
Related: https://bugzilla.kernel.org/show_bug.cgi?id=221454
Hardik Prakash (2):
pinctrl-amd: enable IRQ for WACF2200 touchscreen on Lenovo Yoga 7
14AGP11
i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7
14AGP11
drivers/i2c/busses/i2c-designware-platdrv.c | 81 +++++++++++++++++++++
drivers/pinctrl/pinctrl-amd.c | 35 +++++++++
2 files changed, 116 insertions(+)
--
2.54.0
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-12 7:31 [PATCH " Hardik Prakash @ 2026-05-12 7:31 ` Hardik Prakash 2026-05-12 10:55 ` Andy Shevchenko 0 siblings, 1 reply; 15+ messages in thread From: Hardik Prakash @ 2026-05-12 7:31 UTC (permalink / raw) To: linux-gpio, linux-i2c; +Cc: linus.walleij, wsa, Hardik Prakash The existing dw_i2c_amd_gpio_defer_dmi quirk for Lenovo 83TD checks gpio_dev->driver to determine if the GPIO controller is ready, but this pointer is set before pinctrl-amd's probe completes, causing i2c_designware to probe AMDI0010:02 before the GPIO IRQ quirk runs. Switch to device_is_bound() under device_lock() to correctly defer until GPIO probe has fully completed. Also replace the string-based device lookup with ACPI HID/UID matching for robustness, and add DMI_BOARD_NAME to the DMI match to reduce false positives. Fixes: the lost arbitration on AMDI0010:02 at boot on Lenovo 83TD. Signed-off-by: Hardik Prakash <hardikprakash.official@gmail.com> --- drivers/i2c/busses/i2c-designware-platdrv.c | 81 +++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 3351c4a9ef118..ccf4433a1d4fa 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -8,6 +8,7 @@ * Copyright (C) 2007 MontaVista Software Inc. * Copyright (C) 2009 Provigent Ltd. */ +#include <linux/acpi.h> #include <linux/clk-provider.h> #include <linux/clk.h> #include <linux/delay.h> @@ -86,6 +87,82 @@ static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = { { } /* terminate list */ }; +static const struct dmi_system_id dw_i2c_amd_gpio_defer_dmi[] = { + { + .ident = "Lenovo Yoga 7 14AGP11", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83TD"), + DMI_MATCH(DMI_BOARD_NAME, "LNVNB161216"), + }, + }, + { } /* terminate list */ +}; + +struct dw_i2c_hid_uid { + const char *hid; + u64 uid; +}; + +static int dw_i2c_match_hid_uid(struct device *dev, const void *data) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + const struct dw_i2c_hid_uid *id = data; + + if (!adev) + return 0; + + return acpi_dev_hid_uid_match(adev, id->hid, id->uid); +} + +static struct device *dw_i2c_find_platform_hid_uid(const char *hid, u64 uid) +{ + struct dw_i2c_hid_uid data = { + .hid = hid, + .uid = uid, + }; + + return bus_find_device(&platform_bus_type, NULL, &data, dw_i2c_match_hid_uid); +} + +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) +{ + struct acpi_device *adev = ACPI_COMPANION(device); + + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) + return false; + if (!adev) + return false; + + return acpi_dev_hid_uid_match(adev, "AMDI0010", 2); +} + +static int dw_i2c_defer_for_amd_gpio(struct device *device) +{ + struct device *gpio_dev; + + if (!dw_i2c_needs_amd_gpio_dep(device)) + return 0; + + gpio_dev = dw_i2c_find_platform_hid_uid("AMDI0030", 0); + if (!gpio_dev) + return -EPROBE_DEFER; + + device_lock(gpio_dev); + if (!device_is_bound(gpio_dev)) { + device_unlock(gpio_dev); + put_device(gpio_dev); + return -EPROBE_DEFER; + } + device_unlock(gpio_dev); + + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) + dev_warn(device, "failed to add device link to AMDI0030:00\n"); + + put_device(gpio_dev); + return 0; +} + static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = { #ifdef CONFIG_I2C_DESIGNWARE_BAYTRAIL { @@ -138,6 +215,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) struct dw_i2c_dev *dev; int irq, ret; + ret = dw_i2c_defer_for_amd_gpio(device); + if (ret) + return ret; + irq = platform_get_irq_optional(pdev, 0); if (irq == -ENXIO) flags |= ACCESS_POLLING; -- 2.54.0 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 2026-05-12 7:31 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash @ 2026-05-12 10:55 ` Andy Shevchenko [not found] ` <CANTFpSX-U5pJ3zQ7NMQMpSu+bw1wB5weW7E-oQ51oE7oZg1cZw@mail.gmail.com> 0 siblings, 1 reply; 15+ messages in thread From: Andy Shevchenko @ 2026-05-12 10:55 UTC (permalink / raw) To: Hardik Prakash; +Cc: linux-gpio, linux-i2c, linus.walleij, wsa On Tue, May 12, 2026 at 01:01:39PM +0530, Hardik Prakash wrote: > The existing dw_i2c_amd_gpio_defer_dmi quirk for Lenovo 83TD checks Existing? Is this message and the whole stuff is somehow AI-assisted? > gpio_dev->driver to determine if the GPIO controller is ready, but > this pointer is set before pinctrl-amd's probe completes, causing > i2c_designware to probe AMDI0010:02 before the GPIO IRQ quirk runs. > > Switch to device_is_bound() under device_lock() to correctly defer > until GPIO probe has fully completed. Also replace the string-based > device lookup with ACPI HID/UID matching for robustness, and add > DMI_BOARD_NAME to the DMI match to reduce false positives. > Fixes: the lost arbitration on AMDI0010:02 at boot on Lenovo 83TD. This is incorrect way of providing a Fixes tag. ... > +struct dw_i2c_hid_uid { > + const char *hid; > + u64 uid; > +}; Useless as duplicates the existing strictures. See also below. ... > +static int dw_i2c_match_hid_uid(struct device *dev, const void *data) > +{ > + struct acpi_device *adev = ACPI_COMPANION(dev); > + const struct dw_i2c_hid_uid *id = data; > + > + if (!adev) > + return 0; > + > + return acpi_dev_hid_uid_match(adev, id->hid, id->uid); > +} > + > +static struct device *dw_i2c_find_platform_hid_uid(const char *hid, u64 uid) > +{ > + struct dw_i2c_hid_uid data = { > + .hid = hid, > + .uid = uid, > + }; > + > + return bus_find_device(&platform_bus_type, NULL, &data, dw_i2c_match_hid_uid); > +} > + > +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) > +{ > + struct acpi_device *adev = ACPI_COMPANION(device); > + > + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) > + return false; > + if (!adev) > + return false; > + > + return acpi_dev_hid_uid_match(adev, "AMDI0010", 2); > +} The whole flow is just a repetition of acpi_dev_get_first_match_dev(). ... > +static int dw_i2c_defer_for_amd_gpio(struct device *device) > +{ > + struct device *gpio_dev; > + > + if (!dw_i2c_needs_amd_gpio_dep(device)) > + return 0; > + > + gpio_dev = dw_i2c_find_platform_hid_uid("AMDI0030", 0); > + if (!gpio_dev) > + return -EPROBE_DEFER; > + > + device_lock(gpio_dev); > + if (!device_is_bound(gpio_dev)) { > + device_unlock(gpio_dev); > + put_device(gpio_dev); > + return -EPROBE_DEFER; > + } > + device_unlock(gpio_dev); Interesting dance. Needs a comment explaining what's going on here and why this deferral probe won't be a problem in other scenarios. > + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) This needs a good comment explaining what's going on. > + dev_warn(device, "failed to add device link to AMDI0030:00\n"); Why :00? Is it guaranteed that this is going to be with :00? Note, this suffix is instance number in Linux and strictly speaking might differ even from boot to boot on the same machine. > + put_device(gpio_dev); > + return 0; > +} -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <CANTFpSX-U5pJ3zQ7NMQMpSu+bw1wB5weW7E-oQ51oE7oZg1cZw@mail.gmail.com>]
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 [not found] ` <CANTFpSX-U5pJ3zQ7NMQMpSu+bw1wB5weW7E-oQ51oE7oZg1cZw@mail.gmail.com> @ 2026-05-12 11:10 ` Hardik Prakash 2026-05-12 18:05 ` Andy Shevchenko 1 sibling, 0 replies; 15+ messages in thread From: Hardik Prakash @ 2026-05-12 11:10 UTC (permalink / raw) To: Andy Shevchenko; +Cc: linux-gpio, linux-i2c, linus.walleij, wsa Thanks for taking the time to review, Andy. To answer your question directly: yes, this patch series was indeed written with significant AI assistance (Claude, GPT-Codex). I used it to navigate ACPI analysis, interpret GPIO register diffs, and draft code I don't yet have the kernel experience to write from scratch. I performed the investigation, testing, and hardware debugging, but I want to be transparent about the process. On the technical points: 1. "Existing?": My bad, the commit message is indeed wrong. The dw_i2c_amd_gpio_defer_dmi table and dw_i2c_add_amd_gpio_link function are added by patch 2 and do not pre-exist. I'll fix the commit message in v2. 2. Fixes tag: Noted. I will use the correct format with a commit hash in v2. 3. dw_i2c_hid_uid struct duplicating existing structures: I will take a look at acpi_dev_get_first_match_dev() and simplify accordingly. 4. device_lock deferral probe: I will add one explaining the race between driver pointer set and probe completion. 5. device_link_add comment: will add. 6. ":00" suffix hardcoded in the warning: Understood. Will correct this. I'll send a v2 addressing all of these. Is there anything else you'd like addressed before I do? Hardik On Tue, 12 May 2026 at 16:37, Hardik Prakash <hardikprakash.official@gmail.com> wrote: > > Thanks for taking the time to review, Andy. > > To answer your question directly: yes, this patch series was indeed written with significant AI assistance (Claude, GPT-Codex). I used it to navigate ACPI analysis, interpret GPIO register diffs, and draft code I don't yet have the kernel experience to write from scratch. I performed the investigation, testing, and hardware debugging, but I want to be transparent about the process. > > On the technical points: > > "Existing?": My bad, the commit message is indeed wrong. The dw_i2c_amd_gpio_defer_dmi table and dw_i2c_add_amd_gpio_link function are added by patch 2 and do not pre-exist. I'll fix the commit message in v2. > Fixes tag: Noted. I will use the correct format with a commit hash in v2. > dw_i2c_hid_uid struct duplicating existing structures: I will take a look at acpi_dev_get_first_match_dev() and simplify accordingly. > device_lock deferral probe: I will add one explaining the race between driver pointer set and probe completion. > device_link_add comment: will add. > ":00" suffix hardcoded in the warning: Understood. Will correct this. > > I'll send a v2 addressing all of these. Is there anything else you'd like addressed before I do? > > Hardik > > > > On Tue, 12 May 2026 at 16:25, Andy Shevchenko <andriy.shevchenko@intel.com> wrote: >> >> On Tue, May 12, 2026 at 01:01:39PM +0530, Hardik Prakash wrote: >> > The existing dw_i2c_amd_gpio_defer_dmi quirk for Lenovo 83TD checks >> >> Existing? Is this message and the whole stuff is somehow AI-assisted? >> >> > gpio_dev->driver to determine if the GPIO controller is ready, but >> > this pointer is set before pinctrl-amd's probe completes, causing >> > i2c_designware to probe AMDI0010:02 before the GPIO IRQ quirk runs. >> > >> > Switch to device_is_bound() under device_lock() to correctly defer >> > until GPIO probe has fully completed. Also replace the string-based >> > device lookup with ACPI HID/UID matching for robustness, and add >> > DMI_BOARD_NAME to the DMI match to reduce false positives. >> >> > Fixes: the lost arbitration on AMDI0010:02 at boot on Lenovo 83TD. >> >> This is incorrect way of providing a Fixes tag. >> >> ... >> >> > +struct dw_i2c_hid_uid { >> > + const char *hid; >> > + u64 uid; >> > +}; >> >> Useless as duplicates the existing strictures. See also below. >> >> ... >> >> > +static int dw_i2c_match_hid_uid(struct device *dev, const void *data) >> > +{ >> > + struct acpi_device *adev = ACPI_COMPANION(dev); >> > + const struct dw_i2c_hid_uid *id = data; >> > + >> > + if (!adev) >> > + return 0; >> > + >> > + return acpi_dev_hid_uid_match(adev, id->hid, id->uid); >> > +} >> > + >> > +static struct device *dw_i2c_find_platform_hid_uid(const char *hid, u64 uid) >> > +{ >> > + struct dw_i2c_hid_uid data = { >> > + .hid = hid, >> > + .uid = uid, >> > + }; >> > + >> > + return bus_find_device(&platform_bus_type, NULL, &data, dw_i2c_match_hid_uid); >> > +} >> > + >> > +static bool dw_i2c_needs_amd_gpio_dep(struct device *device) >> > +{ >> > + struct acpi_device *adev = ACPI_COMPANION(device); >> > + >> > + if (!dmi_check_system(dw_i2c_amd_gpio_defer_dmi)) >> > + return false; >> > + if (!adev) >> > + return false; >> > + >> > + return acpi_dev_hid_uid_match(adev, "AMDI0010", 2); >> > +} >> >> The whole flow is just a repetition of acpi_dev_get_first_match_dev(). >> >> ... >> >> > +static int dw_i2c_defer_for_amd_gpio(struct device *device) >> > +{ >> > + struct device *gpio_dev; >> > + >> > + if (!dw_i2c_needs_amd_gpio_dep(device)) >> > + return 0; >> > + >> > + gpio_dev = dw_i2c_find_platform_hid_uid("AMDI0030", 0); >> > + if (!gpio_dev) >> > + return -EPROBE_DEFER; >> > + >> > + device_lock(gpio_dev); >> > + if (!device_is_bound(gpio_dev)) { >> > + device_unlock(gpio_dev); >> > + put_device(gpio_dev); >> > + return -EPROBE_DEFER; >> > + } >> > + device_unlock(gpio_dev); >> >> Interesting dance. Needs a comment explaining what's going on here and why this >> deferral probe won't be a problem in other scenarios. >> >> > + if (!device_link_add(device, gpio_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) >> >> This needs a good comment explaining what's going on. >> >> > + dev_warn(device, "failed to add device link to AMDI0030:00\n"); >> >> Why :00? Is it guaranteed that this is going to be with :00? Note, this suffix >> is instance number in Linux and strictly speaking might differ even from boot >> to boot on the same machine. >> >> > + put_device(gpio_dev); >> > + return 0; >> > +} >> >> -- >> With Best Regards, >> Andy Shevchenko >> >> ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO on Lenovo Yoga 7 14AGP11 [not found] ` <CANTFpSX-U5pJ3zQ7NMQMpSu+bw1wB5weW7E-oQ51oE7oZg1cZw@mail.gmail.com> 2026-05-12 11:10 ` Hardik Prakash @ 2026-05-12 18:05 ` Andy Shevchenko 1 sibling, 0 replies; 15+ messages in thread From: Andy Shevchenko @ 2026-05-12 18:05 UTC (permalink / raw) To: Hardik Prakash; +Cc: linux-gpio, linux-i2c, linus.walleij, wsa On Tue, May 12, 2026 at 04:37:58PM +0530, Hardik Prakash wrote: First of all, please do not top-post! > Thanks for taking the time to review, Andy. > > To answer your question directly: yes, this patch series was indeed written > with significant AI assistance (Claude, GPT-Codex). I used it to navigate > ACPI analysis, interpret GPIO register diffs, and draft code I don't yet > have the kernel experience to write from scratch. I performed the > investigation, testing, and hardware debugging, but I want to be > transparent about the process. So, please study the kernel documentation about AI assistance. This has to be clearly mentioned in the commit message (we have special tag nowadays, Assisted-by: IIRC). > On the technical points: > > 1. "Existing?": My bad, the commit message is indeed wrong. The > dw_i2c_amd_gpio_defer_dmi table and dw_i2c_add_amd_gpio_link function are > added by patch 2 and do not pre-exist. I'll fix the commit message in v2. > 2. Fixes tag: Noted. I will use the correct format with a commit hash in > v2. > 3. dw_i2c_hid_uid struct duplicating existing structures: I will take a > look at acpi_dev_get_first_match_dev() and simplify accordingly. > 4. device_lock deferral probe: I will add one explaining the race > between driver pointer set and probe completion. > 5. device_link_add comment: will add. > 6. ":00" suffix hardcoded in the warning: Understood. Will correct this. > > I'll send a v2 addressing all of these. Is there anything else you'd like > addressed before I do? Two things that I mentioned above. The rest will see when there is the v2 appears. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-05-14 5:43 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 6:13 [PATCH v2 0/2] Fix WACF2200 touchscreen on Lenovo Yoga 7 14AGP11 Hardik Prakash
2026-05-13 6:13 ` [PATCH 1/2] pinctrl-amd: enable IRQ for " Hardik Prakash
2026-05-13 7:36 ` Linus Walleij
2026-05-13 17:23 ` Mario Limonciello
[not found] ` <CANTFpSUr7KWMA5D7wh48f5-Ty9hDo7U7Ydsob32YZuZ83dRiiw@mail.gmail.com>
2026-05-14 5:12 ` Hardik Prakash
2026-05-13 6:13 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash
2026-05-13 17:12 ` Andy Shevchenko
2026-05-13 17:28 ` Mario Limonciello
[not found] ` <CANTFpSU=94RuX1uFf4UitRyzLPvu=cTF_S5khjjJNQUU1T_PtA@mail.gmail.com>
2026-05-14 5:14 ` Hardik Prakash
2026-05-14 5:43 ` Hardik Prakash
2026-05-13 17:03 ` [PATCH v2 0/2] Fix WACF2200 touchscreen " Andy Shevchenko
-- strict thread matches above, loose matches on Subject: below --
2026-05-12 7:31 [PATCH " Hardik Prakash
2026-05-12 7:31 ` [PATCH 2/2] i2c: designware: fix probe ordering for AMD GPIO " Hardik Prakash
2026-05-12 10:55 ` Andy Shevchenko
[not found] ` <CANTFpSX-U5pJ3zQ7NMQMpSu+bw1wB5weW7E-oQ51oE7oZg1cZw@mail.gmail.com>
2026-05-12 11:10 ` Hardik Prakash
2026-05-12 18:05 ` Andy Shevchenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox