aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-05 18:56:28 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-05 22:29:02 -0500
commitb881d53770e68f3f9b6097a61dd1685180393f20 (patch)
tree4a4a05083e2cb58ab45c33e3632e0eabd832b54d /drivers/input
parent6c8afa88adce613c23f27e719f805cc2a6441b07 (diff)
Input: evdev - do not queue SYN_DROPPED if queue is empty
There is no point in queueing EV_SYN/SYN_DROPPED on clock type change when there are no events in the client's queue and doing so confuses tests in libinput package, so let's not do that. Reported-and-tested-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/evdev.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index e7cee3880b75..a18f41b89b6a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -108,10 +108,8 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
108 client->head = head; 108 client->head = head;
109} 109}
110 110
111/* queue SYN_DROPPED event and flush queue if flush parameter is true */ 111static void __evdev_queue_syn_dropped(struct evdev_client *client)
112static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
113{ 112{
114 unsigned long flags;
115 struct input_event ev; 113 struct input_event ev;
116 ktime_t time; 114 ktime_t time;
117 115
@@ -126,11 +124,6 @@ static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
126 ev.code = SYN_DROPPED; 124 ev.code = SYN_DROPPED;
127 ev.value = 0; 125 ev.value = 0;
128 126
129 spin_lock_irqsave(&client->buffer_lock, flags);
130
131 if (flush)
132 client->packet_head = client->head = client->tail;
133
134 client->buffer[client->head++] = ev; 127 client->buffer[client->head++] = ev;
135 client->head &= client->bufsize - 1; 128 client->head &= client->bufsize - 1;
136 129
@@ -139,12 +132,21 @@ static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
139 client->tail = (client->head - 1) & (client->bufsize - 1); 132 client->tail = (client->head - 1) & (client->bufsize - 1);
140 client->packet_head = client->tail; 133 client->packet_head = client->tail;
141 } 134 }
135}
136
137static void evdev_queue_syn_dropped(struct evdev_client *client)
138{
139 unsigned long flags;
142 140
141 spin_lock_irqsave(&client->buffer_lock, flags);
142 __evdev_queue_syn_dropped(client);
143 spin_unlock_irqrestore(&client->buffer_lock, flags); 143 spin_unlock_irqrestore(&client->buffer_lock, flags);
144} 144}
145 145
146static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) 146static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
147{ 147{
148 unsigned long flags;
149
148 if (client->clk_type == clkid) 150 if (client->clk_type == clkid)
149 return 0; 151 return 0;
150 152
@@ -163,8 +165,18 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
163 return -EINVAL; 165 return -EINVAL;
164 } 166 }
165 167
166 /* Flush pending events and queue SYN_DROPPED event.*/ 168 /*
167 evdev_queue_syn_dropped(client, true); 169 * Flush pending events and queue SYN_DROPPED event,
170 * but only if the queue is not empty.
171 */
172 spin_lock_irqsave(&client->buffer_lock, flags);
173
174 if (client->head != client->tail) {
175 client->packet_head = client->head = client->tail;
176 __evdev_queue_syn_dropped(client);
177 }
178
179 spin_unlock_irqrestore(&client->buffer_lock, flags);
168 180
169 return 0; 181 return 0;
170} 182}
@@ -803,7 +815,7 @@ static int evdev_handle_get_val(struct evdev_client *client,
803 815
804 ret = bits_to_user(mem, maxbit, maxlen, p, compat); 816 ret = bits_to_user(mem, maxbit, maxlen, p, compat);
805 if (ret < 0) 817 if (ret < 0)
806 evdev_queue_syn_dropped(client, false); 818 evdev_queue_syn_dropped(client);
807 819
808 kfree(mem); 820 kfree(mem);
809 821