Skip to content

Commit

Permalink
Input: evdev - fix bug in checking duplicate clock change request
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Aniroop Mathur authored and Dmitry Torokhov committed Oct 31, 2015
1 parent 5523662 commit bf5f18d
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit bf5f18d

Please sign in to comment.