Some elantech touchpads consistently fail after resuming from suspend at sanity_check in elantech_packet_check_v4. This means the touchpad is completely unusable after suspend resume. With different permutations of i8042 nomux, nopnp, reset, and noloop kernel options enabled, and with crc_enabled the touchpad fails in the same way. Resyncing the touchpad after receiving the PACKET_UNKNOWN/PSMOUSE_BAD_DATA return code allows the touchpad to function correctly on resume. The touchpad fails to reconnect with the serio reconnect no matter how many times it retries, so this change skips over that retry sequence and goes directly to resync. Signed-off-by: Jonathan Denose <jdenose@xxxxxxxxxx> --- drivers/input/mouse/psmouse-base.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index a0aac76b1e41d..3c6eefcb9582f 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -12,6 +12,7 @@ #include <linux/bitops.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/interrupt.h> @@ -105,6 +106,16 @@ static struct attribute *psmouse_dev_attrs[] = { ATTRIBUTE_GROUPS(psmouse_dev); +static const struct dmi_system_id resync_on_resume[] = { + { + .ident = "Lenovo N24", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo N24"), + }, + } +}; + /* * psmouse_mutex protects all operations changing state of mouse * (connecting, disconnecting, changing rate or resolution via @@ -285,6 +296,12 @@ static int psmouse_handle_byte(struct psmouse *psmouse) "%s at %s lost sync at byte %d\n", psmouse->name, psmouse->phys, psmouse->pktcnt); + if (dmi_check_system(resync_on_resume)) { + psmouse_notice(psmouse, "issuing resync request"); + __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); + psmouse_queue_work(psmouse, &psmouse->resync_work, 0); + return -EIO; + } if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { __psmouse_set_state(psmouse, PSMOUSE_IGNORE); psmouse_notice(psmouse, -- 2.42.0.820.g83a721a137-goog