* [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
@ 2026-09-30 6:22 Waqar Gulzar via B4 Relay
2026-09-30 6:35 ` sashiko-bot
0 siblings, 1 reply; 4+ messages in thread
From: Waqar Gulzar via B4 Relay @ 2026-09-30 6:22 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, linux-acpi, stable, Waqar Gulzar
From: Waqar Gulzar <iamwaqargulzar@gmail.com>
On the HP OmniBook X Flip 16 the ELAN2514 touchscreen interrupt is a
GPIO pad (GPP_E_18) routed directly to the IO-APIC. The firmware's
touchscreen power resource does
PTPL._ON: \_SB.SGRA (TPI2, TPIP) // TPIP = T0IP = 0
PTPL._OFF: \_SB.SGRA (TPI2, TPIP ^ 1)
while the device's _INI enables routing with SGRA (GPLI, T0IP ^ 1).
So _ON clears PADCFG0.GPIROUTIOXAPIC and disconnects the pad from the
IO-APIC. Linux evaluates _ON at probe and on every D3->D0 transition
(Windows apparently does not while _STA already reports the resource
on), after which the level-triggered IRQ never deasserts:
- ~630 interrupts/s while idle, nearly every read returns 0xffff
- frames shifted by a leading 0xff, "incomplete report (67/7167)"
- stylus reports arrive at ~25 Hz instead of the native ~268 Hz
- touch stalls and false stylus proximity
Re-enable the routing through the firmware's own \_SB.SGRA helper from
the power_up hook, which runs at probe and on resume before the HID
reset.
Tested on board 8DA1 (BIOS F.20): idle interrupts drop from ~630/s to
0 after boot and after s2idle resume, and pen and touch behave as on
Windows. Board 8DA0 is the other board ID of this model and is reported
to have the same firmware code, so it is included, but it has not been
tested because I do not have access to one.
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2142384
Link: https://github.com/testyfishy/hp-omnibook-flip16-touchscreen-fix
Link: https://github.com/iamwaqargulzar/hp-omnibook-x-flip-16-linux-touchscreen-pen-fix
Cc: stable@vger.kernel.org
Signed-off-by: Waqar Gulzar <iamwaqargulzar@gmail.com>
---
The HP OmniBook X Flip 16 firmware disconnects the ELAN2514 touchscreen
interrupt from the IO-APIC in its power resource _ON method, which Linux
runs at probe and resume. This patch re-enables the routing through the
firmware's own helper from i2c-hid-acpi's power_up hook.
Tested on board 8DA1 with BIOS F.20 on Linux 7.2.8, including s2idle
resume. The 8DA0 entry is untested (I do not have that board).
Full analysis, ACPI excerpts, and Windows/Linux traces:
https://github.com/iamwaqargulzar/hp-omnibook-x-flip-16-linux-touchscreen-pen-fix
---
drivers/hid/i2c-hid/i2c-hid-acpi.c | 58 ++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
index 9371db200..b6348ee3d 100644
--- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
+++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -21,6 +21,7 @@
#include <linux/acpi.h>
#include <linux/device.h>
+#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -55,6 +56,60 @@ static void i2c_hid_acpi_restore_sequence(struct i2chid_ops *ops)
i2c_hid_acpi_get_descriptor(ihid_acpi->adev);
}
+/*
+ * HP OmniBook X Flip 16 (boards 8DA0/8DA1): the touchscreen power resource
+ * \_SB.PC00.I2C4.PTPL._ON writes the wrong value to the GPIROUTIOXAPIC bit
+ * of the touchscreen interrupt pad, disconnecting it from the IO-APIC. The
+ * level-triggered interrupt then never deasserts, the controller is read
+ * continuously (~630 reads/s while idle) and it cannot deliver pen reports
+ * at its native rate. Windows does not run _ON while the resource already
+ * reports on, so it is not affected. Linux runs _ON at probe and on every
+ * resume, so re-enable the routing with the firmware's own helper before
+ * the HID reset.
+ */
+static const struct dmi_system_id i2c_hid_acpi_irq_route_dmi[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "8DA0"),
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "8DA1"),
+ },
+ },
+ { }
+};
+
+static int i2c_hid_acpi_restore_irq_route(struct i2chid_ops *ops)
+{
+ struct i2c_hid_acpi *ihid_acpi = container_of(ops, struct i2c_hid_acpi, ops);
+ union acpi_object args[2];
+ struct acpi_object_list arg_list = { ARRAY_SIZE(args), args };
+ unsigned long long pad;
+ acpi_status status;
+
+ status = acpi_evaluate_integer(NULL, "\\GPLI", NULL, &pad);
+ if (ACPI_FAILURE(status))
+ return 0;
+
+ args[0].type = ACPI_TYPE_INTEGER;
+ args[0].integer.value = pad;
+ args[1].type = ACPI_TYPE_INTEGER;
+ args[1].integer.value = 1;
+
+ status = acpi_evaluate_object(NULL, "\\_SB.SGRA", &arg_list, NULL);
+ if (ACPI_FAILURE(status))
+ acpi_handle_warn(acpi_device_handle(ihid_acpi->adev),
+ "failed to restore interrupt routing: %s\n",
+ acpi_format_exception(status));
+
+ /* Never fail probe or resume because of this workaround */
+ return 0;
+}
+
static void i2c_hid_acpi_shutdown_tail(struct i2chid_ops *ops)
{
struct i2c_hid_acpi *ihid_acpi = container_of(ops, struct i2c_hid_acpi, ops);
@@ -85,6 +140,9 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
ihid_acpi->adev = adev;
ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
ihid_acpi->ops.restore_sequence = i2c_hid_acpi_restore_sequence;
+ if (acpi_dev_hid_uid_match(ihid_acpi->adev, "ELAN2514", NULL) &&
+ dmi_check_system(i2c_hid_acpi_irq_route_dmi))
+ ihid_acpi->ops.power_up = i2c_hid_acpi_restore_irq_route;
acpi_device_fix_up_power(adev);
---
base-commit: 145c2b2e9a5c0f794fb4009bcb072ab19f8ccfcd
change-id: 20260930-b4-elan2514-irq-route-d8274fcf805b
Best regards,
--
Waqar Gulzar <iamwaqargulzar@gmail.com>
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
2026-09-30 6:22 [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16 Waqar Gulzar via B4 Relay
@ 2026-09-30 6:35 ` sashiko-bot
2026-09-30 7:20 ` Waqar Gulzar
0 siblings, 1 reply; 4+ messages in thread
From: sashiko-bot @ 2026-09-30 6:35 UTC (permalink / raw)
To: Waqar Gulzar; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] hid: i2c-hid-acpi: IRQ routing quirk bypassed on resume if wakeup enabled
--
commit c1ea0adbfc4956d2ccd0cfccdc56448c010e7ac2
Author: Waqar Gulzar <iamwaqargulzar@gmail.com>
HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
The HP OmniBook X Flip 16 firmware disconnects the ELAN2514 touchscreen
interrupt from the IO-APIC in its power resource _ON method, which Linux
runs at probe and resume. This patch re-enables the routing through the
firmware's own helper from i2c-hid-acpi's power_up hook.
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2142384
Link: https://github.com/testyfishy/hp-omnibook-flip16-touchscreen-fix
Link: https://github.com/iamwaqargulzar/hp-omnibook-x-flip-16-linux-touchscreen-pen-fix
> diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
> index 9371db200fc4d..b6348ee3d422b 100644
> --- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
> +++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
[ ... ]
> @@ -85,6 +140,9 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
> ihid_acpi->adev = adev;
> ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
> ihid_acpi->ops.restore_sequence = i2c_hid_acpi_restore_sequence;
> + if (acpi_dev_hid_uid_match(ihid_acpi->adev, "ELAN2514", NULL) &&
> + dmi_check_system(i2c_hid_acpi_irq_route_dmi))
> + ihid_acpi->ops.power_up = i2c_hid_acpi_restore_irq_route;
[Severity: Medium]
Will this quirk be reliably applied on resume if the device has wakeup enabled?
The quirk is hooked up to the power_up callback. However, in
i2c_hid_core_resume() the core driver conditionally skips the power_up
callback if wakeup is enabled:
drivers/hid/i2c-hid/i2c-hid-core.c:i2c_hid_core_resume() {
...
if (!device_may_wakeup(&client->dev))
i2c_hid_core_power_up(ihid);
...
}
If the user or system enables wakeup for the touchscreen,
i2c_hid_core_resume() skips i2c_hid_core_power_up(). If the device's ACPI
power resource was turned off during sleep, _ON will execute on resume and
break the IRQ routing again, but the power_up quirk will not run to fix it.
Does the quirk need to run unconditionally on resume instead of being tied
to the core's power management logic?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260930-b4-elan2514-irq-route-v1-1-44671bf01d05@gmail.com?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
2026-09-30 6:35 ` sashiko-bot
@ 2026-09-30 7:20 ` Waqar Gulzar
0 siblings, 0 replies; 4+ messages in thread
From: Waqar Gulzar @ 2026-09-30 7:20 UTC (permalink / raw)
To: sashiko-reviews; +Cc: dmitry.torokhov, linux-input
On Wed, 30 Sept 2026 at 11:35, <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] hid: i2c-hid-acpi: IRQ routing quirk bypassed on resume if wakeup enabled
> --
>
> commit c1ea0adbfc4956d2ccd0cfccdc56448c010e7ac2
> Author: Waqar Gulzar <iamwaqargulzar@gmail.com>
>
> HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
>
> The HP OmniBook X Flip 16 firmware disconnects the ELAN2514 touchscreen
> interrupt from the IO-APIC in its power resource _ON method, which Linux
> runs at probe and resume. This patch re-enables the routing through the
> firmware's own helper from i2c-hid-acpi's power_up hook.
>
> Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2142384
> Link: https://github.com/testyfishy/hp-omnibook-flip16-touchscreen-fix
> Link: https://github.com/iamwaqargulzar/hp-omnibook-x-flip-16-linux-touchscreen-pen-fix
>
> > diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c
> > index 9371db200fc4d..b6348ee3d422b 100644
> > --- a/drivers/hid/i2c-hid/i2c-hid-acpi.c
> > +++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
>
> [ ... ]
>
> > @@ -85,6 +140,9 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
> > ihid_acpi->adev = adev;
> > ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
> > ihid_acpi->ops.restore_sequence = i2c_hid_acpi_restore_sequence;
> > + if (acpi_dev_hid_uid_match(ihid_acpi->adev, "ELAN2514", NULL) &&
> > + dmi_check_system(i2c_hid_acpi_irq_route_dmi))
> > + ihid_acpi->ops.power_up = i2c_hid_acpi_restore_irq_route;
>
> [Severity: Medium]
> Will this quirk be reliably applied on resume if the device has wakeup enabled?
>
> The quirk is hooked up to the power_up callback. However, in
> i2c_hid_core_resume() the core driver conditionally skips the power_up
> callback if wakeup is enabled:
>
> drivers/hid/i2c-hid/i2c-hid-core.c:i2c_hid_core_resume() {
> ...
> if (!device_may_wakeup(&client->dev))
> i2c_hid_core_power_up(ihid);
> ...
> }
>
> If the user or system enables wakeup for the touchscreen,
> i2c_hid_core_resume() skips i2c_hid_core_power_up(). If the device's ACPI
> power resource was turned off during sleep, _ON will execute on resume and
> break the IRQ routing again, but the power_up quirk will not run to fix it.
>
> Does the quirk need to run unconditionally on resume instead of being tied
> to the core's power management logic?
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260930-b4-elan2514-irq-route-v1-1-44671bf01d05@gmail.com?part=1
> Will this quirk be reliably applied on resume if the device has wakeup enabled?
On the affected boards it cannot have wakeup enabled. The touchscreen's
ACPI device (\_SB.PC00.I2C4.TPL1) has no _PRW, so it is not wakeup-capable:
there is no power/wakeup attribute for the i2c client, it is not listed in
/proc/acpi/wakeup, and device_may_wakeup() is always false. So
i2c_hid_core_resume() always calls power_up here, which matches the test
result (the IRQ stays idle after s2idle resume).
I agree the dependency is implicit. If the maintainers prefer, I can send a
v2 that either documents this assumption in a comment or makes the routing
fix independent of the wakeup state.
Thanks,
Waqar
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16
[not found] <20260930-b4-elan2514-irq-route-v1-1-a7ab598efbc5@gmail.com>
@ 2026-10-05 7:49 ` Waqar Gulzar
0 siblings, 0 replies; 4+ messages in thread
From: Waqar Gulzar @ 2026-10-05 7:49 UTC (permalink / raw)
To: iamwaqargulzar
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel,
linux-acpi, stable
Additional data since posting: the same firmware bug and fix were
confirmed by other owners using an equivalent ACPI table override:
- OmniBook X Flip 16, board 8DA1, BIOS F.10, ELAN 04F3:43EF
- OmniBook 7 Flip 16-au0773cl, board 8DA0, BIOS F.08, ELAN 04F3:43EF
- a third 8DA1 unit (BIOS F.10, 04F3:43F5) shows the same ~620 IRQ/s
storm
Correction to the commit message: 8DA0 is the HP OmniBook 7 Flip 16,
a sibling model, not a second board ID of the OmniBook X Flip 16. The
DMI match is correct as is; I will fix the wording in v2 if one is
needed.
Details: https://bugzilla.kernel.org/show_bug.cgi?id=220854
Thanks,
Waqar
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-05 7:49 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-30 6:22 [PATCH] HID: i2c-hid-acpi: restore touchscreen IRQ routing on HP OmniBook X Flip 16 Waqar Gulzar via B4 Relay
2026-09-30 6:35 ` sashiko-bot
2026-09-30 7:20 ` Waqar Gulzar
[not found] <20260930-b4-elan2514-irq-route-v1-1-a7ab598efbc5@gmail.com>
2026-10-05 7:49 ` Waqar Gulzar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox