* [PATCH 0/2] Input: synaptics - enable SMBus for ThinkPad P14s Gen 2i (LEN2072)
@ 2026-10-26 9:31 Dmitry Mikushin
2026-10-26 9:31 ` [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention Dmitry Mikushin
2026-10-26 9:31 ` [PATCH 2/2] Input: synaptics - add LEN2072 to smbus_pnp_ids for ThinkPad P14s Gen 2i Dmitry Mikushin
0 siblings, 2 replies; 4+ messages in thread
From: Dmitry Mikushin @ 2026-10-26 9:31 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Dmitry Mikushin, linux-input, linux-kernel
The ThinkPad P14s Gen 2i touchpad (Synaptics TM3471-030, LEN2072) is
not on the SMBus passlist and runs in PS/2 mode. Forcing RMI4 alone
does not help: the F12 attention handler reads the whole 79-byte data
packet over SMBus on every frame, which caps the report rate at about
43 Hz and loses fast swipes.
Patch 1 makes F12 read only the object data it consumes, raising the
report rate to about 65 Hz on this machine. Patch 2 then adds LEN2072
to smbus_pnp_ids. Patch 2 should not be applied without patch 1.
Both were tested on a ThinkPad P14s Gen 2i (20VX) on 7.2.9, including
s2idle suspend/resume and the TrackPoint on the RMI4 pass-through port.
Dmitry Mikushin (2):
Input: synaptics-rmi4 - f12: read only the object data on attention
Input: synaptics - add LEN2072 to smbus_pnp_ids for ThinkPad P14s Gen
2i
drivers/input/mouse/synaptics.c | 1 +
drivers/input/rmi4/rmi_f12.c | 16 +++++++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention 2026-10-26 9:31 [PATCH 0/2] Input: synaptics - enable SMBus for ThinkPad P14s Gen 2i (LEN2072) Dmitry Mikushin @ 2026-10-26 9:31 ` Dmitry Mikushin 2026-10-26 10:31 ` sashiko-bot 2026-10-26 9:31 ` [PATCH 2/2] Input: synaptics - add LEN2072 to smbus_pnp_ids for ThinkPad P14s Gen 2i Dmitry Mikushin 1 sibling, 1 reply; 4+ messages in thread From: Dmitry Mikushin @ 2026-10-26 9:31 UTC (permalink / raw) To: Dmitry Torokhov; +Cc: Dmitry Mikushin, linux-input, linux-kernel When F12 data is not supplied by the transport as attention data, the attention handler reads the whole F12 data packet on every interrupt, although only Data1 (the object reports) is consumed. The remaining data registers are never used. On SMBus this transfer is the dominant per-frame cost. On a ThinkPad P14s Gen 2i with a Synaptics TM3471-030 (i801 SMBus) the F12 data packet is 79 bytes, of which Data1 is the first 32. Reading 79 bytes takes about 17.4 ms and reading 32 bytes about 7.3 ms. With the full read the touchpad reports at about 43 Hz (median 23.0 ms between frames), and fast swipes yield only a handful of frames, so they are mostly lost to pointer acceleration and smoothing. Reading only Data1 raises the report rate to about 65 Hz (median 15.3 ms between frames), measured with a finger on the same machine. Compute the size of the leading registers up to and including Data1 at probe time and read only that much. The attention data path (hid-rmi) is unchanged. Signed-off-by: Dmitry Mikushin <dmitry@kernelgen.org> --- drivers/input/rmi4/rmi_f12.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c index 841884d967..ad210464b2 100644 --- a/drivers/input/rmi4/rmi_f12.c +++ b/drivers/input/rmi4/rmi_f12.c @@ -58,6 +58,8 @@ struct f12_data { const struct rmi_register_desc_item *data15; u16 data15_offset; + u32 read_size; + unsigned long irq_mask[]; }; @@ -269,8 +271,9 @@ static irqreturn_t rmi_f12_attention(int irq, void *ctx) drvdata->attn_data.data += valid_bytes; drvdata->attn_data.size -= valid_bytes; } else { + valid_bytes = f12->read_size; retval = rmi_read_block(rmi_dev, f12->data_addr, - sensor->data_pkt, sensor->pkt_size); + sensor->data_pkt, valid_bytes); if (retval < 0) { dev_err(&fn->dev, "Failed to read object data. Code: %d.\n", retval); @@ -529,6 +532,17 @@ static int rmi_f12_probe(struct rmi_function *fn) data_offset += item->reg_size; } + /* + * Only Data1 (object reports) is consumed when the data registers + * are read from the device, so do not read the remaining registers + * on every attention. On SMBus this transfer dominates the per-frame + * cost and therefore limits the report rate. + */ + f12->read_size = sensor->pkt_size; + if (f12->data1) + f12->read_size = min_t(u32, sensor->pkt_size, + f12->data1_offset + f12->data1->reg_size); + /* allocate the in-kernel tracking buffers */ sensor->tracking_pos = devm_kcalloc(&fn->dev, sensor->nbr_fingers, sizeof(*sensor->tracking_pos), -- 2.56.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention 2026-10-26 9:31 ` [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention Dmitry Mikushin @ 2026-10-26 10:31 ` sashiko-bot 0 siblings, 0 replies; 4+ messages in thread From: sashiko-bot @ 2026-10-26 10:31 UTC (permalink / raw) To: Dmitry Mikushin; +Cc: linux-input, dmitry.torokhov Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Input: rmi4: unadjusted valid_bytes in rmi_f12_attention() reads past data1 -- commit c4b3a9b641a3a2e611195ada64fab67096a67d47 Author: Dmitry Mikushin <dmitry@kernelgen.org> Input: synaptics-rmi4 - f12: read only the object data on attention This commit optimizes F12 attention handling when attention data is not supplied by the transport by computing the size of the leading registers up to and including Data1 at probe time and reading only that prefix instead of the full F12 data packet. > diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c > index 841884d967a3d..ad210464b2f34 100644 > --- a/drivers/input/rmi4/rmi_f12.c > +++ b/drivers/input/rmi4/rmi_f12.c > @@ -58,6 +58,8 @@ struct f12_data { > const struct rmi_register_desc_item *data15; > u16 data15_offset; > > + u32 read_size; > + > unsigned long irq_mask[]; > }; > > @@ -269,8 +271,9 @@ static irqreturn_t rmi_f12_attention(int irq, void *ctx) > drvdata->attn_data.data += valid_bytes; > drvdata->attn_data.size -= valid_bytes; > } else { > + valid_bytes = f12->read_size; > retval = rmi_read_block(rmi_dev, f12->data_addr, > - sensor->data_pkt, sensor->pkt_size); > + sensor->data_pkt, valid_bytes); > if (retval < 0) { > dev_err(&fn->dev, "Failed to read object data. Code: %d.\n", > retval); > @@ -529,6 +532,17 @@ static int rmi_f12_probe(struct rmi_function *fn) > data_offset += item->reg_size; > } > > + /* > + * Only Data1 (object reports) is consumed when the data registers > + * are read from the device, so do not read the remaining registers > + * on every attention. On SMBus this transfer dominates the per-frame > + * cost and therefore limits the report rate. > + */ > + f12->read_size = sensor->pkt_size; > + if (f12->data1) > + f12->read_size = min_t(u32, sensor->pkt_size, > + f12->data1_offset + f12->data1->reg_size); [Severity: High] Can this read past the end of Data1 into uninitialized memory in sensor->data_pkt[] or out-of-bounds past sensor->data_pkt[] when Data0 is present in the F12 data register descriptor (so f12->data1_offset > 0)? In rmi_f12_probe(), sensor->data_pkt is allocated with devm_kmalloc() without zero-initialization: drivers/input/rmi4/rmi_f12.c:rmi_f12_probe() { ... sensor->data_pkt = devm_kmalloc(&fn->dev, sensor->pkt_size, GFP_KERNEL); ... } In rmi_f12_attention(), rmi_read_block() now populates only the first valid_bytes (f12->read_size = f12->data1_offset + f12->data1->reg_size) bytes of sensor->data_pkt, leaving any trailing bytes of sensor->data_pkt uninitialized, and then passes &sensor->data_pkt[f12->data1_offset] with the unadjusted valid_bytes to rmi_f12_process_objects(): drivers/input/rmi4/rmi_f12.c:rmi_f12_attention() { ... if (f12->data1) rmi_f12_process_objects(f12, &sensor->data_pkt[f12->data1_offset], valid_bytes); ... } Inside rmi_f12_process_objects(), size is treated as the number of valid bytes starting at data1 (&sensor->data_pkt[f12->data1_offset]): drivers/input/rmi4/rmi_f12.c:rmi_f12_process_objects() { struct rmi_2d_sensor *sensor = &f12->sensor; u32 objects = min(f12->data1->num_subpackets, size / F12_DATA1_BYTES_PER_OBJ); ... } Because rmi_parse_register_desc_item() parses item->reg_size and item->num_subpackets independently, if f12->data1->reg_size is smaller than f12->data1->num_subpackets * F12_DATA1_BYTES_PER_OBJ (or if valid_bytes on the attn_data path is smaller than f12->data1_offset + f12->data1->num_subpackets * F12_DATA1_BYTES_PER_OBJ), rmi_f12_process_objects() can read up to f12->data1_offset bytes past sensor->data_pkt[valid_bytes - 1], reporting uninitialized kernel heap memory to userspace via input events or reading past the end of sensor->data_pkt[]. Should rmi_f12_attention() check that valid_bytes > f12->data1_offset and pass valid_bytes - f12->data1_offset to rmi_f12_process_objects()? -- Sashiko AI review · https://sashiko.dev/#/patchset/20261026093118.2312302-1-dmitry@kernelgen.org?part=1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] Input: synaptics - add LEN2072 to smbus_pnp_ids for ThinkPad P14s Gen 2i 2026-10-26 9:31 [PATCH 0/2] Input: synaptics - enable SMBus for ThinkPad P14s Gen 2i (LEN2072) Dmitry Mikushin 2026-10-26 9:31 ` [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention Dmitry Mikushin @ 2026-10-26 9:31 ` Dmitry Mikushin 1 sibling, 0 replies; 4+ messages in thread From: Dmitry Mikushin @ 2026-10-26 9:31 UTC (permalink / raw) To: Dmitry Torokhov; +Cc: Dmitry Mikushin, linux-input, linux-kernel The ThinkPad P14s Gen 2i (20VX) has a Synaptics TM3471-030 touchpad (PNP ID LEN2072, firmware 3324237) that supports SMBus/RMI4, but it is not in smbus_pnp_ids[], so psmouse drives it in legacy PS/2 mode. There it is limited to two tracked contacts and shares the i8042 channel with the TrackPoint. With psmouse.synaptics_intertouch=1 the touchpad binds to rmi4 at SMBus address 0x2c, reports four contacts, and the TrackPoint keeps working through the RMI4 pass-through port. Suspend/resume (s2idle) works. Add LEN2072 to the smbus_pnp_ids[] passlist. Signed-off-by: Dmitry Mikushin <dmitry@kernelgen.org> --- drivers/input/mouse/synaptics.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 1ed9261bff..b007e642ea 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -194,6 +194,7 @@ static const char * const smbus_pnp_ids[] = { "LEN2058", /* E490 */ "LEN205b", /* T490 */ "LEN2068", /* T14 Gen 1 */ + "LEN2072", /* P14s Gen 2i */ "SYN1221", /* TUXEDO InfinityBook Pro 14 v5 */ "SYN3003", /* HP EliteBook 850 G1 */ "SYN3015", /* HP EliteBook 840 G2 */ -- 2.56.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-26 10:31 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-26 9:31 [PATCH 0/2] Input: synaptics - enable SMBus for ThinkPad P14s Gen 2i (LEN2072) Dmitry Mikushin 2026-10-26 9:31 ` [PATCH 1/2] Input: synaptics-rmi4 - f12: read only the object data on attention Dmitry Mikushin 2026-10-26 10:31 ` sashiko-bot 2026-10-26 9:31 ` [PATCH 2/2] Input: synaptics - add LEN2072 to smbus_pnp_ids for ThinkPad P14s Gen 2i Dmitry Mikushin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.