aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAniroop Mathur <a.mathur@samsung.com>2015-10-30 07:15:37 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-10-31 13:35:02 -0400
commitbf5f18d708802737fa0db6306f6b9148f85b2efd (patch)
tree65c8baf0c1896214fd90de355767ba14586b9a8b
parent5523662edd4fe937267053c2018b75be2ac17860 (diff)
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>
-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 {
56 struct fasync_struct *fasync; 56 struct fasync_struct *fasync;
57 struct evdev *evdev; 57 struct evdev *evdev;
58 struct list_head node; 58 struct list_head node;
59 int clk_type; 59 unsigned int clk_type;
60 bool revoked; 60 bool revoked;
61 unsigned long *evmasks[EV_CNT]; 61 unsigned long *evmasks[EV_CNT];
62 unsigned int bufsize; 62 unsigned int bufsize;
@@ -191,37 +191,39 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
191static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) 191static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
192{ 192{
193 unsigned long flags; 193 unsigned long flags;
194 194 unsigned int clk_type;
195 if (client->clk_type == clkid)
196 return 0;
197 195
198 switch (clkid) { 196 switch (clkid) {
199 197
200 case CLOCK_REALTIME: 198 case CLOCK_REALTIME:
201 client->clk_type = EV_CLK_REAL; 199 clk_type = EV_CLK_REAL;
202 break; 200 break;
203 case CLOCK_MONOTONIC: 201 case CLOCK_MONOTONIC:
204 client->clk_type = EV_CLK_MONO; 202 clk_type = EV_CLK_MONO;
205 break; 203 break;
206 case CLOCK_BOOTTIME: 204 case CLOCK_BOOTTIME:
207 client->clk_type = EV_CLK_BOOT; 205 clk_type = EV_CLK_BOOT;
208 break; 206 break;
209 default: 207 default:
210 return -EINVAL; 208 return -EINVAL;
211 } 209 }
212 210
213 /* 211 if (client->clk_type != clk_type) {
214 * Flush pending events and queue SYN_DROPPED event, 212 client->clk_type = clk_type;
215 * but only if the queue is not empty.
216 */
217 spin_lock_irqsave(&client->buffer_lock, flags);
218 213
219 if (client->head != client->tail) { 214 /*
220 client->packet_head = client->head = client->tail; 215 * Flush pending events and queue SYN_DROPPED event,
221 __evdev_queue_syn_dropped(client); 216 * but only if the queue is not empty.
222 } 217 */
218 spin_lock_irqsave(&client->buffer_lock, flags);
223 219
224 spin_unlock_irqrestore(&client->buffer_lock, flags); 220 if (client->head != client->tail) {
221 client->packet_head = client->head = client->tail;
222 __evdev_queue_syn_dropped(client);
223 }
224
225 spin_unlock_irqrestore(&client->buffer_lock, flags);
226 }
225 227
226 return 0; 228 return 0;
227} 229}