From: djedi <edwards.richard.ai@gmail.com>
To: linux-input@vger.kernel.org
Cc: Jiri Kosina <jikos@kernel.org>, Benjamin Tissoires <bentiss@kernel.org>
Subject: i2c-hid: Goodix GXTP5100 (27c6:01e9) touch engine latches off when probed early at boot
Date: Fri, 10 Jul 2026 15:56:59 +0200 [thread overview]
Message-ID: <178369181961.1607113.5474217277993277808@gmail.com> (raw)
Hello,
I'm hitting a reproducible boot-time race on a laptop touchpad and I'd
like input on whether the existing i2c-hid quirk mechanism is the right
place to fix it, or whether I'm looking in the wrong layer. I have a
speculative sketch patch but I'm not confident enough in it to send as a
real submission -- details on why below, and I'd rather ask than send a
patch I can't stand behind.
Hardware
--------
Lenovo ThinkBook 16 G7+ IAH (type 21TL), DMI pvrThinkBook16G7+IAH.
Touchpad: Goodix GXTP5100 haptic pressure pad, i2c-hid over ACPI
(i2c_hid_acpi), USB/i2c ID 27c6:01e9, i2c-1, bound to hid-multitouch.
Kernel: 7.0.12 (also reproduced identically on 6.12.95 -- this is not a
kernel-version regression, both exhibit it).
Symptom
-------
When i2c_hid_acpi probes this device during early boot, the touch
ENGINE latches off permanently: the i2c front end keeps ACKing and the
device enumerates completely normally (identical kernel probe trace
whether the pad ends up dead or alive -- see below), but no touch input
ever arrives. It survives an EC reset. The only way to clear it is a
full power loss to the pad (cold boot; a warm/soft reboot is not
sufficient).
Evidence
--------
1. Identical probe trace regardless of outcome. From journalctl across
both a "dead" boot and a "revived" one (same day, same kernel):
kernel: hid-generic 0018:27C6:01E9.0001: item 0 1 0 11 parsing failed
kernel: hid-generic 0018:27C6:01E9.0001: probe with driver hid-generic failed with error -22
kernel: hid-multitouch 0018:27C6:01E9.0001: GT7868Q report descriptor fixup is applied.
kernel: input: GXTP5100:00 27C6:01E9 as .../input/input3
kernel: input: GXTP5100:00 27C6:01E9 as .../input/input4
kernel: hid-multitouch 0018:27C6:01E9.0001: input,hidraw0: I2C HID v1.00 Mouse [GXTP5100:00 27C6:01E9] on i2c-GXTP5100:00
These lines are byte-for-byte identical on a boot where the pad ends
up completely unresponsive and on a boot where it works fine. The
kernel-visible probe/bind sequence gives no signal that anything is
wrong -- whatever differs is happening inside the Goodix firmware's
touch engine, below what i2c-hid observes.
2. IRQ evidence. On a dead pad, the shared i2c controller line still
flows (protocol/ACK traffic keeps working) but the touch controller's
dedicated GPIO IRQ line stays at 0 forever. On a working pad, both
flow, e.g. currently on this machine:
32: ... 41998 IR-IO-APIC 32-fasteoi idma64.0, i2c_designware.0 (i2c bus IRQ)
235: ... 1031 intel-gpio 182 GXTP5100:00 (touch IRQ, climbing with use)
3. Recovery is 100% correlated with power-cycling the pad, not with any
driver-level reset, EC reset, or software reload -- only removing and
restoring power to the Goodix chip itself clears the latch.
4. Empirical fix: blacklisting i2c_hid_acpi at early boot and loading it
~15s later via a oneshot systemd unit (after multi-user.target) makes
the pad come up working consistently. Delaying the probe, not
retrying it, resolves it -- consistent with a firmware-internal
power-on/wakeup race that needs time to settle before anything
touches the device.
Precedent I found, and why I'm not just sending that patch
------------------------------------------------------------
drivers/hid/i2c-hid/i2c-hid-core.c already has a quirk for a sibling
Goodix device, 27c6:0d42:
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
with the comment:
"On Goodix 27c6:0d42 wait extra time before device wakeup. It's not
clear why but if we send wakeup too early, the device will never
trigger input interrupts."
That is a striking match for our symptom description. I went and read
where I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME is actually consumed,
though, and it's only checked inside i2c_hid_core_resume() -- it never
fires during __i2c_hid_core_probe()/i2c_hid_core_probe() at all. Our
repro is a cold-boot/first-probe symptom; this machine never exercises
suspend/resume in any of this investigation (sleep targets are masked
system-wide here because s2idle hard-freezes the box, unrelated issue).
So simply adding 27c6:01e9 to that same quirk table entry would compile
fine and do nothing for us, since the code path that applies it is never
reached on a cold boot. I don't want to send a one-line patch I already
know wouldn't fix anything.
I also noticed I2C_DEVICE_ID_GOODIX_01E9 (0x01e9) is already defined in
drivers/hid/hid-ids.h and used in hid-multitouch.c for the GT7868Q
report-descriptor fixup and device-ID table -- so this exact ID is known
to the HID subsystem already, just not wired into the i2c-hid-core quirk
table or anything probe-time-delay-related.
What I'm asking
----------------
Is there an existing, preferred way to delay the *first* wakeup/reset
handshake after a fresh probe (as opposed to after a resume) for a
device like this? Candidates I can see, roughly in order of how
surgical they'd be, but I'd defer entirely to your judgment:
a) A new quirk flag applied inside __i2c_hid_core_probe() /
i2c_hid_core_probe(), analogous in shape to
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME but for the probe path.
b) Something at the ACPI power-resource layer -- i2c_hid_acpi_probe()
in i2c-hid-acpi.c calls acpi_device_fix_up_power() right before
i2c_hid_core_probe(); if the race is really about the ACPI power
resource turning on the rail and the chip's internal boot sequence
not being done yet, that might be a better layer than i2c-hid-core.
c) Something Goodix-firmware-specific that doesn't belong in i2c-hid
at all.
I have a rough, deliberately-labeled-speculative sketch of option (a)
that I'm attaching inline below for discussion only -- it is untested,
unbuilt, and not something I'm asking you to merge. If (a) or (b) sounds
right to you I'm glad to build a test kernel, reproduce on this exact
hardware (I have a reliable dead-boot repro and a known-working
late-modprobe workaround to compare against), capture before/after
/proc/interrupts, and send a real patch with a proper commit message and
sign-off.
Current workaround, for reference (not something I'm proposing upstream,
just so the symptom description is fully reproducible by others):
/etc/modprobe.d/goodix-tpad-lateload.conf:
blacklist i2c_hid_acpi
/etc/systemd/system/tpad-lateload.service:
[Unit]
Description=Late-load Goodix GXTP5100 touchpad driver (boot-time wakeup race workaround)
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 15
ExecStart=/sbin/modprobe i2c_hid_acpi
[Install]
WantedBy=multi-user.target
Speculative sketch (RFC only, not a submission -- see caveats above)
---------------------------------------------------------------------
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -52,6 +52,7 @@
#define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5)
#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6)
#define I2C_HID_QUIRK_RE_POWER_ON BIT(7)
+#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE BIT(8) /* RFC, see this thread */
/* Command opcodes */
#define I2C_HID_OPCODE_RESET 0x01
@@ -149,6 +150,16 @@
I2C_HID_QUIRK_BOGUS_IRQ },
{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
+ /*
+ * RFC: 27c6:01e9 (GXTP5100, e.g. Lenovo ThinkBook 16 G7+ IAH)
+ * appears to latch its touch engine off if probed too early
+ * after a cold boot; untested guess at the same class of fix
+ * as the 0d42 resume quirk above, applied at first probe.
+ */
+ { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01E9,
+ I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE },
{ I2C_VENDOR_ID_BLTP, I2C_PRODUCT_ID_BLTP7853,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ 0, 0 }
@@ -1292,6 +1303,12 @@
ret = __i2c_hid_core_probe(ihid);
if (ret < 0)
goto err_power_down;
+
+ /* RFC: see I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE comment
+ * above -- untested, guessing at parity with the
+ * resume-path quirk.
+ */
+ if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_PROBE)
+ msleep(1500);
}
ret = i2c_hid_init_irq(client);
Thanks for reading this far, and happy to provide any more detail,
dmesg, or i2cdump output you'd like.
djedi
edwardsr99@gmail.com
reply other threads:[~2026-07-10 13:57 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178369181961.1607113.5474217277993277808@gmail.com \
--to=edwards.richard.ai@gmail.com \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox