summaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2023-05-15 16:14:29 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2023-05-18 11:40:32 -0700
commitc4c7eac8ee78d896635ce05d7a1c3f813fcbe24c (patch)
tree4ae7840b6467ff2a8584cf32938c1b65461cf345 /drivers/input/mouse
parent7d674f9150c361e5b992551b46516d41eede3722 (diff)
downloadlinux-stable-c4c7eac8ee78d896635ce05d7a1c3f813fcbe24c.tar.gz
linux-stable-c4c7eac8ee78d896635ce05d7a1c3f813fcbe24c.tar.bz2
linux-stable-c4c7eac8ee78d896635ce05d7a1c3f813fcbe24c.zip
Input: libps2 - introduce common interrupt handler
Instead of exposing inner workings of libps2 to drivers such as atkbd and psmouse, have them define pre-receive and receive callbacks, and provide a common handler that can be used with underlying serio port. While at this add kerneldoc to the module. Link: https://lore.kernel.org/r/ZGK81cxqjr/KS1kA@google.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/psmouse-base.c53
1 files changed, 23 insertions, 30 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index ed5376099fba..a0aac76b1e41 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -336,17 +336,14 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
}
}
-/*
- * psmouse_interrupt() handles incoming characters, either passing them
- * for normal processing or gathering them as command response.
- */
-static irqreturn_t psmouse_interrupt(struct serio *serio,
- u8 data, unsigned int flags)
+static enum ps2_disposition psmouse_pre_receive_byte(struct ps2dev *ps2dev,
+ u8 data,
+ unsigned int flags)
{
- struct psmouse *psmouse = psmouse_from_serio(serio);
+ struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev);
if (psmouse->state == PSMOUSE_IGNORE)
- goto out;
+ return PS2_IGNORE;
if (unlikely((flags & SERIO_TIMEOUT) ||
((flags & SERIO_PARITY) &&
@@ -357,27 +354,25 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
"bad data from KBC -%s%s\n",
flags & SERIO_TIMEOUT ? " timeout" : "",
flags & SERIO_PARITY ? " bad parity" : "");
- ps2_cmd_aborted(&psmouse->ps2dev);
- goto out;
+ return PS2_ERROR;
}
if (flags & SERIO_OOB_DATA) {
psmouse_handle_oob_data(psmouse, data);
- goto out;
+ return PS2_IGNORE;
}
- if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
- if (ps2_handle_ack(&psmouse->ps2dev, data))
- goto out;
+ return PS2_PROCESS;
+}
- if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_CMD))
- if (ps2_handle_response(&psmouse->ps2dev, data))
- goto out;
+static void psmouse_receive_byte(struct ps2dev *ps2dev, u8 data)
+{
+ struct psmouse *psmouse = container_of(ps2dev, struct psmouse, ps2dev);
- pm_wakeup_event(&serio->dev, 0);
+ pm_wakeup_event(&ps2dev->serio->dev, 0);
if (psmouse->state <= PSMOUSE_RESYNCING)
- goto out;
+ return;
if (psmouse->state == PSMOUSE_ACTIVATED &&
psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) {
@@ -386,7 +381,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
- goto out;
+ return;
}
psmouse->packet[psmouse->pktcnt++] = data;
@@ -395,21 +390,21 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
if (psmouse->pktcnt == 1) {
psmouse->last = jiffies;
- goto out;
+ return;
}
if (psmouse->packet[1] == PSMOUSE_RET_ID ||
(psmouse->protocol->type == PSMOUSE_HGPK &&
psmouse->packet[1] == PSMOUSE_RET_BAT)) {
__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
- serio_reconnect(serio);
- goto out;
+ serio_reconnect(ps2dev->serio);
+ return;
}
/* Not a new device, try processing first byte normally */
psmouse->pktcnt = 1;
if (psmouse_handle_byte(psmouse))
- goto out;
+ return;
psmouse->packet[psmouse->pktcnt++] = data;
}
@@ -424,14 +419,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
- goto out;
+ return;
}
psmouse->last = jiffies;
psmouse_handle_byte(psmouse);
-
- out:
- return IRQ_HANDLED;
}
/*
@@ -1604,7 +1596,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
if (!psmouse || !input_dev)
goto err_free;
- ps2_init(&psmouse->ps2dev, serio);
+ ps2_init(&psmouse->ps2dev, serio,
+ psmouse_pre_receive_byte, psmouse_receive_byte);
INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
@@ -1786,7 +1779,7 @@ static struct serio_driver psmouse_drv = {
},
.description = DRIVER_DESC,
.id_table = psmouse_serio_ids,
- .interrupt = psmouse_interrupt,
+ .interrupt = ps2_interrupt,
.connect = psmouse_connect,
.reconnect = psmouse_reconnect,
.fast_reconnect = psmouse_fast_reconnect,