Input: psmouse - implement fast reconnect option
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 6 Mar 2017 07:19:22 +0000 (23:19 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 25 Mar 2017 17:37:27 +0000 (10:37 -0700)
Make use of serio's fast reconnect option and allow psmouse protocol
handler's to implement fast reconnect handlers that will be called during
system resume.

Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h

index a598b7223cef2fc60f1df135856ac5dd669b86d6..47fd2976da7fbd6d469d912035edd452e01dfb73 100644 (file)
@@ -966,6 +966,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
        psmouse->protocol_handler = psmouse_process_byte;
        psmouse->pktsize = 3;
        psmouse->reconnect = NULL;
+       psmouse->fast_reconnect = NULL;
        psmouse->disconnect = NULL;
        psmouse->cleanup = NULL;
        psmouse->pt_activate = NULL;
@@ -1628,15 +1629,26 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
        goto out;
 }
 
-static int psmouse_reconnect(struct serio *serio)
+static int __psmouse_reconnect(struct serio *serio, bool fast_reconnect)
 {
        struct psmouse *psmouse = serio_get_drvdata(serio);
        struct psmouse *parent = NULL;
+       int (*reconnect_handler)(struct psmouse *);
        unsigned char type;
        int rc = -1;
 
        mutex_lock(&psmouse_mutex);
 
+       if (fast_reconnect) {
+               reconnect_handler = psmouse->fast_reconnect;
+               if (!reconnect_handler) {
+                       rc = -ENOENT;
+                       goto out_unlock;
+               }
+       } else {
+               reconnect_handler = psmouse->reconnect;
+       }
+
        if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
                parent = serio_get_drvdata(serio->parent);
                psmouse_deactivate(parent);
@@ -1644,8 +1656,8 @@ static int psmouse_reconnect(struct serio *serio)
 
        psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
-       if (psmouse->reconnect) {
-               if (psmouse->reconnect(psmouse))
+       if (reconnect_handler) {
+               if (reconnect_handler(psmouse))
                        goto out;
        } else {
                psmouse_reset(psmouse);
@@ -1677,10 +1689,21 @@ out:
        if (parent)
                psmouse_activate(parent);
 
+out_unlock:
        mutex_unlock(&psmouse_mutex);
        return rc;
 }
 
+static int psmouse_reconnect(struct serio *serio)
+{
+       return __psmouse_reconnect(serio, false);
+}
+
+static int psmouse_fast_reconnect(struct serio *serio)
+{
+       return __psmouse_reconnect(serio, true);
+}
+
 static struct serio_device_id psmouse_serio_ids[] = {
        {
                .type   = SERIO_8042,
@@ -1708,6 +1731,7 @@ static struct serio_driver psmouse_drv = {
        .interrupt      = psmouse_interrupt,
        .connect        = psmouse_connect,
        .reconnect      = psmouse_reconnect,
+       .fast_reconnect = psmouse_fast_reconnect,
        .disconnect     = psmouse_disconnect,
        .cleanup        = psmouse_cleanup,
 };
index 8c83b8e2505cea4e9f77555f4050759432d6bf30..bc76e771812b64289827c62944dd46d41c075e5d 100644 (file)
@@ -80,6 +80,7 @@ struct psmouse {
        void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale);
 
        int (*reconnect)(struct psmouse *psmouse);
+       int (*fast_reconnect)(struct psmouse *psmouse);
        void (*disconnect)(struct psmouse *psmouse);
        void (*cleanup)(struct psmouse *psmouse);
        int (*poll)(struct psmouse *psmouse);