diff options
| author | David S. Miller <davem@davemloft.net> | 2015-02-11 19:48:14 -0800 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-02-11 19:48:14 -0800 |
| commit | 855e7e7174bade3f2b63077a81eea5aab525dbf6 (patch) | |
| tree | 3423eb92315865d76cb8d488513bfef6ab9251d0 /drivers/input/evdev.c | |
| parent | e09dcd2e7913aa50b5cb4836bc1e990e429e4aff (diff) | |
| parent | 59d53737a8640482995fea13c6e2c0fd016115d6 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
I pushed a version of the crypto iov_iter bug fix that
Al Viro wrote, but Linus put in a different copy of the
same fix into his tree.
I then reverted my commit in net-next, and that's why we have a merge
when pulling in Linus's tree.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/input/evdev.c')
| -rw-r--r-- | drivers/input/evdev.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 18d4b2c8fe55..a18f41b89b6a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -62,26 +62,6 @@ struct evdev_client { struct input_event buffer[]; }; -static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) -{ - switch (clkid) { - - case CLOCK_REALTIME: - client->clk_type = EV_CLK_REAL; - break; - case CLOCK_MONOTONIC: - client->clk_type = EV_CLK_MONO; - break; - case CLOCK_BOOTTIME: - client->clk_type = EV_CLK_BOOT; - break; - default: - return -EINVAL; - } - - return 0; -} - /* flush queued events of type @type, caller must hold client->buffer_lock */ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) { @@ -128,10 +108,8 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) client->head = head; } -/* queue SYN_DROPPED event */ -static void evdev_queue_syn_dropped(struct evdev_client *client) +static void __evdev_queue_syn_dropped(struct evdev_client *client) { - unsigned long flags; struct input_event ev; ktime_t time; @@ -146,8 +124,6 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) ev.code = SYN_DROPPED; ev.value = 0; - spin_lock_irqsave(&client->buffer_lock, flags); - client->buffer[client->head++] = ev; client->head &= client->bufsize - 1; @@ -156,8 +132,53 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) client->tail = (client->head - 1) & (client->bufsize - 1); client->packet_head = client->tail; } +} + +static void evdev_queue_syn_dropped(struct evdev_client *client) +{ + unsigned long flags; + + spin_lock_irqsave(&client->buffer_lock, flags); + __evdev_queue_syn_dropped(client); + spin_unlock_irqrestore(&client->buffer_lock, flags); +} + +static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) +{ + unsigned long flags; + + if (client->clk_type == clkid) + return 0; + + switch (clkid) { + + case CLOCK_REALTIME: + client->clk_type = EV_CLK_REAL; + break; + case CLOCK_MONOTONIC: + client->clk_type = EV_CLK_MONO; + break; + case CLOCK_BOOTTIME: + client->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->head != client->tail) { + client->packet_head = client->head = client->tail; + __evdev_queue_syn_dropped(client); + } spin_unlock_irqrestore(&client->buffer_lock, flags); + + return 0; } static void __pass_event(struct evdev_client *client, |
