From aa1264b70480a47d0446b1856e256f715be271b0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 20 Oct 2025 15:35:13 +0200 Subject: [PATCH] 5.15-stable patches added patches: hid-multitouch-fix-sticky-fingers.patch --- .../hid-multitouch-fix-sticky-fingers.patch | 111 ++++++++++++++++++ queue-5.15/series | 1 + 2 files changed, 112 insertions(+) create mode 100644 queue-5.15/hid-multitouch-fix-sticky-fingers.patch diff --git a/queue-5.15/hid-multitouch-fix-sticky-fingers.patch b/queue-5.15/hid-multitouch-fix-sticky-fingers.patch new file mode 100644 index 0000000000..a5bf20f632 --- /dev/null +++ b/queue-5.15/hid-multitouch-fix-sticky-fingers.patch @@ -0,0 +1,111 @@ +From 46f781e0d151844589dc2125c8cce3300546f92a Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Wed, 8 Oct 2025 16:06:58 +0200 +Subject: HID: multitouch: fix sticky fingers + +From: Benjamin Tissoires + +commit 46f781e0d151844589dc2125c8cce3300546f92a upstream. + +The sticky fingers quirk (MT_QUIRK_STICKY_FINGERS) was only considering +the case when slots were not released during the last report. +This can be problematic if the firmware forgets to release a finger +while others are still present. + +This was observed on the Synaptics DLL0945 touchpad found on the Dell +XPS 9310 and the Dell Inspiron 5406. + +Fixes: 4f4001bc76fd ("HID: multitouch: fix rare Win 8 cases when the touch up event gets missing") +Cc: stable@vger.kernel.org +Signed-off-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-multitouch.c | 27 ++++++++++++++------------- + 1 file changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -83,9 +83,8 @@ enum latency_mode { + HID_LATENCY_HIGH = 1, + }; + +-#define MT_IO_FLAGS_RUNNING 0 +-#define MT_IO_FLAGS_ACTIVE_SLOTS 1 +-#define MT_IO_FLAGS_PENDING_SLOTS 2 ++#define MT_IO_SLOTS_MASK GENMASK(7, 0) /* reserve first 8 bits for slot tracking */ ++#define MT_IO_FLAGS_RUNNING 32 + + static const bool mtrue = true; /* default for true */ + static const bool mfalse; /* default for false */ +@@ -161,7 +160,11 @@ struct mt_device { + struct mt_class mtclass; /* our mt device class */ + struct timer_list release_timer; /* to release sticky fingers */ + struct hid_device *hdev; /* hid_device we're attached to */ +- unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ ++ unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING) ++ * first 8 bits are reserved for keeping the slot ++ * states, this is fine because we only support up ++ * to 250 slots (MT_MAX_MAXCONTACT) ++ */ + __u8 inputmode_value; /* InputMode HID feature value */ + __u8 maxcontacts; + bool is_buttonpad; /* is this device a button pad? */ +@@ -936,6 +939,7 @@ static void mt_release_pending_palms(str + + for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) { + clear_bit(slotnum, app->pending_palm_slots); ++ clear_bit(slotnum, &td->mt_io_flags); + + input_mt_slot(input, slotnum); + input_mt_report_slot_inactive(input); +@@ -967,12 +971,6 @@ static void mt_sync_frame(struct mt_devi + + app->num_received = 0; + app->left_button_state = 0; +- +- if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) +- set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags); +- else +- clear_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags); +- clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); + } + + static int mt_compute_timestamp(struct mt_application *app, __s32 value) +@@ -1147,7 +1145,9 @@ static int mt_process_slot(struct mt_dev + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); + input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); + +- set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); ++ set_bit(slotnum, &td->mt_io_flags); ++ } else { ++ clear_bit(slotnum, &td->mt_io_flags); + } + + return 0; +@@ -1282,7 +1282,7 @@ static void mt_touch_report(struct hid_d + * defect. + */ + if (app->quirks & MT_QUIRK_STICKY_FINGERS) { +- if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) ++ if (td->mt_io_flags & MT_IO_SLOTS_MASK) + mod_timer(&td->release_timer, + jiffies + msecs_to_jiffies(100)); + else +@@ -1732,6 +1732,7 @@ static void mt_release_contacts(struct h + for (i = 0; i < mt->num_slots; i++) { + input_mt_slot(input_dev, i); + input_mt_report_slot_inactive(input_dev); ++ clear_bit(i, &td->mt_io_flags); + } + input_mt_sync_frame(input_dev); + input_sync(input_dev); +@@ -1754,7 +1755,7 @@ static void mt_expired_timeout(struct ti + */ + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + return; +- if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) ++ if (td->mt_io_flags & MT_IO_SLOTS_MASK) + mt_release_contacts(hdev); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } diff --git a/queue-5.15/series b/queue-5.15/series index dafec9e1ab..13cbbbe33a 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -12,3 +12,4 @@ drm-exynos-exynos7_drm_decon-properly-clear-channels-during-bind.patch drm-exynos-exynos7_drm_decon-remove-ctx-suspended.patch crypto-rockchip-fix-dma_unmap_sg-nents-value.patch cpufreq-cppc-avoid-using-cpufreq_eternal-as-transition-delay.patch +hid-multitouch-fix-sticky-fingers.patch -- 2.47.3