summaryrefslogtreecommitdiff
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
authorAniroop Mathur <a.mathur@samsung.com>2015-10-30 04:15:37 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-10-31 10:35:02 -0700
commitbf5f18d708802737fa0db6306f6b9148f85b2efd (patch)
tree65c8baf0c1896214fd90de355767ba14586b9a8b /drivers/input/evdev.c
parent5523662edd4fe937267053c2018b75be2ac17860 (diff)
downloadlwn-bf5f18d708802737fa0db6306f6b9148f85b2efd.tar.gz
lwn-bf5f18d708802737fa0db6306f6b9148f85b2efd.zip
Input: evdev - fix bug in checking duplicate clock change request
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>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6b10f5b29218..e9ae3d500a55 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -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;
}