diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -78,8 +78,8 @@ struct focaltech_finger_state { * Absolute position (from the bottom left corner) of the * finger. */ - unsigned int x; - unsigned int y; + int x; + int y; }; /* @@ -108,7 +108,7 @@ struct focaltech_hw_state { }; struct focaltech_data { - unsigned int x_max, y_max; + int x_max, y_max; struct focaltech_hw_state state; }; @@ -126,17 +126,16 @@ static void focaltech_report_state(struct psmouse *psmouse) input_mt_slot(dev, i); input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); if (active) { - unsigned int clamped_x, clamped_y; /* * The touchpad might report invalid data, so we clamp * the resulting values so that we do not confuse - * userspace. + * userspace or accumulate coordinate wind-up. */ - clamped_x = clamp(finger->x, 0U, priv->x_max); - clamped_y = clamp(finger->y, 0U, priv->y_max); - input_report_abs(dev, ABS_MT_POSITION_X, clamped_x); + finger->x = clamp(finger->x, 0, priv->x_max); + finger->y = clamp(finger->y, 0, priv->y_max); + input_report_abs(dev, ABS_MT_POSITION_X, finger->x); input_report_abs(dev, ABS_MT_POSITION_Y, - priv->y_max - clamped_y); + priv->y_max - finger->y); input_report_abs(dev, ABS_TOOL_WIDTH, state->width); } } diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -267,7 +267,15 @@ void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) */ static int psmouse_handle_byte(struct psmouse *psmouse) { - psmouse_ret_t rc = psmouse->protocol_handler(psmouse); + psmouse_ret_t rc; + + /* protocol_handler is NULL when device is being disconnected */ + if (unlikely(!psmouse->protocol_handler)) { + psmouse->pktcnt = 0; + return 0; + } + + rc = psmouse->protocol_handler(psmouse); switch (rc) { case PSMOUSE_BAD_DATA: @@ -1466,6 +1474,9 @@ static void psmouse_disconnect(struct serio *serio) psmouse_deactivate(parent); } + scoped_guard(serio_pause_rx, serio) + psmouse->protocol_handler = NULL; + if (psmouse->disconnect) psmouse->disconnect(psmouse);