Input: evdev - fix bug in checking duplicate clock change request
authorAniroop Mathur <a.mathur@samsung.com>
Fri, 30 Oct 2015 11:15:37 +0000 (04:15 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Sat, 31 Oct 2015 17:35:02 +0000 (10:35 -0700)
clk_type and clkid stores different predefined clock identification
values so they cannot be compared for checking duplicate clock change
request. Therefore, lets fix it to avoid unexpected results.

Signed-off-by: Aniroop Mathur <a.mathur@samsung.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/evdev.c

index 6b10f5b29218fc5dfb48a676fe7a2a3d804e1cb5..e9ae3d500a55e368ed4f1a0b1702e7fbdec0935a 100644 (file)
@@ -56,7 +56,7 @@ struct evdev_client {
        struct fasync_struct *fasync;
        struct evdev *evdev;
        struct list_head node;
-       int clk_type;
+       unsigned int clk_type;
        bool revoked;
        unsigned long *evmasks[EV_CNT];
        unsigned int bufsize;
@@ -191,37 +191,39 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
 static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
 {
        unsigned long flags;
-
-       if (client->clk_type == clkid)
-               return 0;
+       unsigned int clk_type;
 
        switch (clkid) {
 
        case CLOCK_REALTIME:
-               client->clk_type = EV_CLK_REAL;
+               clk_type = EV_CLK_REAL;
                break;
        case CLOCK_MONOTONIC:
-               client->clk_type = EV_CLK_MONO;
+               clk_type = EV_CLK_MONO;
                break;
        case CLOCK_BOOTTIME:
-               client->clk_type = EV_CLK_BOOT;
+               clk_type = EV_CLK_BOOT;
                break;
        default:
                return -EINVAL;
        }
 
-       /*
-        * Flush pending events and queue SYN_DROPPED event,
-        * but only if the queue is not empty.
-        */
-       spin_lock_irqsave(&client->buffer_lock, flags);
+       if (client->clk_type != clk_type) {
+               client->clk_type = clk_type;
 
-       if (client->head != client->tail) {
-               client->packet_head = client->head = client->tail;
-               __evdev_queue_syn_dropped(client);
-       }
+               /*
+                * Flush pending events and queue SYN_DROPPED event,
+                * but only if the queue is not empty.
+                */
+               spin_lock_irqsave(&client->buffer_lock, flags);
 
-       spin_unlock_irqrestore(&client->buffer_lock, flags);
+               if (client->head != client->tail) {
+                       client->packet_head = client->head = client->tail;
+                       __evdev_queue_syn_dropped(client);
+               }
+
+               spin_unlock_irqrestore(&client->buffer_lock, flags);
+       }
 
        return 0;
 }