Commit 87450bd55d6f7caa472b5db49a97ca373baf2577
Exists in
master
and in
4 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: matrix_keypad - increase the limit of rows and columns Input: wacom - fix error path in wacom_probe() Input: ads7846 - check proper condition when freeing gpio Revert "Input: do not pass injected events back to the originating handler" Input: sysrq - rework re-inject logic Input: serio - clear pending rescans after sysfs driver rebind Input: rotary_encoder - use proper irqflags Input: wacom_w8001 - report resolution to userland
Showing 8 changed files Side-by-side Diff
drivers/input/input.c
... | ... | @@ -75,7 +75,6 @@ |
75 | 75 | * dev->event_lock held and interrupts disabled. |
76 | 76 | */ |
77 | 77 | static void input_pass_event(struct input_dev *dev, |
78 | - struct input_handler *src_handler, | |
79 | 78 | unsigned int type, unsigned int code, int value) |
80 | 79 | { |
81 | 80 | struct input_handler *handler; |
... | ... | @@ -94,15 +93,6 @@ |
94 | 93 | continue; |
95 | 94 | |
96 | 95 | handler = handle->handler; |
97 | - | |
98 | - /* | |
99 | - * If this is the handler that injected this | |
100 | - * particular event we want to skip it to avoid | |
101 | - * filters firing again and again. | |
102 | - */ | |
103 | - if (handler == src_handler) | |
104 | - continue; | |
105 | - | |
106 | 96 | if (!handler->filter) { |
107 | 97 | if (filtered) |
108 | 98 | break; |
... | ... | @@ -132,7 +122,7 @@ |
132 | 122 | if (test_bit(dev->repeat_key, dev->key) && |
133 | 123 | is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { |
134 | 124 | |
135 | - input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); | |
125 | + input_pass_event(dev, EV_KEY, dev->repeat_key, 2); | |
136 | 126 | |
137 | 127 | if (dev->sync) { |
138 | 128 | /* |
... | ... | @@ -141,7 +131,7 @@ |
141 | 131 | * Otherwise assume that the driver will send |
142 | 132 | * SYN_REPORT once it's done. |
143 | 133 | */ |
144 | - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | |
134 | + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | |
145 | 135 | } |
146 | 136 | |
147 | 137 | if (dev->rep[REP_PERIOD]) |
... | ... | @@ -174,7 +164,6 @@ |
174 | 164 | #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) |
175 | 165 | |
176 | 166 | static int input_handle_abs_event(struct input_dev *dev, |
177 | - struct input_handler *src_handler, | |
178 | 167 | unsigned int code, int *pval) |
179 | 168 | { |
180 | 169 | bool is_mt_event; |
181 | 170 | |
... | ... | @@ -218,15 +207,13 @@ |
218 | 207 | /* Flush pending "slot" event */ |
219 | 208 | if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { |
220 | 209 | input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); |
221 | - input_pass_event(dev, src_handler, | |
222 | - EV_ABS, ABS_MT_SLOT, dev->slot); | |
210 | + input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); | |
223 | 211 | } |
224 | 212 | |
225 | 213 | return INPUT_PASS_TO_HANDLERS; |
226 | 214 | } |
227 | 215 | |
228 | 216 | static void input_handle_event(struct input_dev *dev, |
229 | - struct input_handler *src_handler, | |
230 | 217 | unsigned int type, unsigned int code, int value) |
231 | 218 | { |
232 | 219 | int disposition = INPUT_IGNORE_EVENT; |
... | ... | @@ -279,8 +266,7 @@ |
279 | 266 | |
280 | 267 | case EV_ABS: |
281 | 268 | if (is_event_supported(code, dev->absbit, ABS_MAX)) |
282 | - disposition = input_handle_abs_event(dev, src_handler, | |
283 | - code, &value); | |
269 | + disposition = input_handle_abs_event(dev, code, &value); | |
284 | 270 | |
285 | 271 | break; |
286 | 272 | |
... | ... | @@ -338,7 +324,7 @@ |
338 | 324 | dev->event(dev, type, code, value); |
339 | 325 | |
340 | 326 | if (disposition & INPUT_PASS_TO_HANDLERS) |
341 | - input_pass_event(dev, src_handler, type, code, value); | |
327 | + input_pass_event(dev, type, code, value); | |
342 | 328 | } |
343 | 329 | |
344 | 330 | /** |
... | ... | @@ -367,7 +353,7 @@ |
367 | 353 | |
368 | 354 | spin_lock_irqsave(&dev->event_lock, flags); |
369 | 355 | add_input_randomness(type, code, value); |
370 | - input_handle_event(dev, NULL, type, code, value); | |
356 | + input_handle_event(dev, type, code, value); | |
371 | 357 | spin_unlock_irqrestore(&dev->event_lock, flags); |
372 | 358 | } |
373 | 359 | } |
... | ... | @@ -397,8 +383,7 @@ |
397 | 383 | rcu_read_lock(); |
398 | 384 | grab = rcu_dereference(dev->grab); |
399 | 385 | if (!grab || grab == handle) |
400 | - input_handle_event(dev, handle->handler, | |
401 | - type, code, value); | |
386 | + input_handle_event(dev, type, code, value); | |
402 | 387 | rcu_read_unlock(); |
403 | 388 | |
404 | 389 | spin_unlock_irqrestore(&dev->event_lock, flags); |
405 | 390 | |
... | ... | @@ -611,10 +596,10 @@ |
611 | 596 | for (code = 0; code <= KEY_MAX; code++) { |
612 | 597 | if (is_event_supported(code, dev->keybit, KEY_MAX) && |
613 | 598 | __test_and_clear_bit(code, dev->key)) { |
614 | - input_pass_event(dev, NULL, EV_KEY, code, 0); | |
599 | + input_pass_event(dev, EV_KEY, code, 0); | |
615 | 600 | } |
616 | 601 | } |
617 | - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | |
602 | + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | |
618 | 603 | } |
619 | 604 | } |
620 | 605 | |
621 | 606 | |
... | ... | @@ -889,9 +874,9 @@ |
889 | 874 | !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && |
890 | 875 | __test_and_clear_bit(old_keycode, dev->key)) { |
891 | 876 | |
892 | - input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); | |
877 | + input_pass_event(dev, EV_KEY, old_keycode, 0); | |
893 | 878 | if (dev->sync) |
894 | - input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); | |
879 | + input_pass_event(dev, EV_SYN, SYN_REPORT, 1); | |
895 | 880 | } |
896 | 881 | |
897 | 882 | out: |
drivers/input/misc/rotary_encoder.c
... | ... | @@ -176,7 +176,7 @@ |
176 | 176 | |
177 | 177 | /* request the IRQs */ |
178 | 178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, |
179 | - IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | |
179 | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | |
180 | 180 | DRV_NAME, encoder); |
181 | 181 | if (err) { |
182 | 182 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
... | ... | @@ -185,7 +185,7 @@ |
185 | 185 | } |
186 | 186 | |
187 | 187 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, |
188 | - IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, | |
188 | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | |
189 | 189 | DRV_NAME, encoder); |
190 | 190 | if (err) { |
191 | 191 | dev_err(&pdev->dev, "unable to request IRQ %d\n", |
drivers/input/serio/serio.c
... | ... | @@ -188,7 +188,8 @@ |
188 | 188 | kfree(event); |
189 | 189 | } |
190 | 190 | |
191 | -static void serio_remove_duplicate_events(struct serio_event *event) | |
191 | +static void serio_remove_duplicate_events(void *object, | |
192 | + enum serio_event_type type) | |
192 | 193 | { |
193 | 194 | struct serio_event *e, *next; |
194 | 195 | unsigned long flags; |
195 | 196 | |
... | ... | @@ -196,13 +197,13 @@ |
196 | 197 | spin_lock_irqsave(&serio_event_lock, flags); |
197 | 198 | |
198 | 199 | list_for_each_entry_safe(e, next, &serio_event_list, node) { |
199 | - if (event->object == e->object) { | |
200 | + if (object == e->object) { | |
200 | 201 | /* |
201 | 202 | * If this event is of different type we should not |
202 | 203 | * look further - we only suppress duplicate events |
203 | 204 | * that were sent back-to-back. |
204 | 205 | */ |
205 | - if (event->type != e->type) | |
206 | + if (type != e->type) | |
206 | 207 | break; |
207 | 208 | |
208 | 209 | list_del_init(&e->node); |
... | ... | @@ -245,7 +246,7 @@ |
245 | 246 | break; |
246 | 247 | } |
247 | 248 | |
248 | - serio_remove_duplicate_events(event); | |
249 | + serio_remove_duplicate_events(event->object, event->type); | |
249 | 250 | serio_free_event(event); |
250 | 251 | } |
251 | 252 | |
252 | 253 | |
... | ... | @@ -436,10 +437,12 @@ |
436 | 437 | } else if (!strncmp(buf, "rescan", count)) { |
437 | 438 | serio_disconnect_port(serio); |
438 | 439 | serio_find_driver(serio); |
440 | + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | |
439 | 441 | } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { |
440 | 442 | serio_disconnect_port(serio); |
441 | 443 | error = serio_bind_driver(serio, to_serio_driver(drv)); |
442 | 444 | put_driver(drv); |
445 | + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); | |
443 | 446 | } else { |
444 | 447 | error = -EINVAL; |
445 | 448 | } |
drivers/input/tablet/wacom_sys.c
drivers/input/touchscreen/ads7846.c
... | ... | @@ -941,29 +941,30 @@ |
941 | 941 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
942 | 942 | int err; |
943 | 943 | |
944 | - /* REVISIT when the irq can be triggered active-low, or if for some | |
944 | + /* | |
945 | + * REVISIT when the irq can be triggered active-low, or if for some | |
945 | 946 | * reason the touchscreen isn't hooked up, we don't need to access |
946 | 947 | * the pendown state. |
947 | 948 | */ |
948 | - if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { | |
949 | - dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | |
950 | - return -EINVAL; | |
951 | - } | |
952 | 949 | |
953 | 950 | if (pdata->get_pendown_state) { |
954 | 951 | ts->get_pendown_state = pdata->get_pendown_state; |
955 | - return 0; | |
956 | - } | |
952 | + } else if (gpio_is_valid(pdata->gpio_pendown)) { | |
957 | 953 | |
958 | - err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | |
959 | - if (err) { | |
960 | - dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | |
961 | - pdata->gpio_pendown); | |
962 | - return err; | |
963 | - } | |
954 | + err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); | |
955 | + if (err) { | |
956 | + dev_err(&spi->dev, "failed to request pendown GPIO%d\n", | |
957 | + pdata->gpio_pendown); | |
958 | + return err; | |
959 | + } | |
964 | 960 | |
965 | - ts->gpio_pendown = pdata->gpio_pendown; | |
961 | + ts->gpio_pendown = pdata->gpio_pendown; | |
966 | 962 | |
963 | + } else { | |
964 | + dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); | |
965 | + return -EINVAL; | |
966 | + } | |
967 | + | |
967 | 968 | return 0; |
968 | 969 | } |
969 | 970 | |
... | ... | @@ -1353,7 +1354,7 @@ |
1353 | 1354 | err_put_regulator: |
1354 | 1355 | regulator_put(ts->reg); |
1355 | 1356 | err_free_gpio: |
1356 | - if (ts->gpio_pendown != -1) | |
1357 | + if (!ts->get_pendown_state) | |
1357 | 1358 | gpio_free(ts->gpio_pendown); |
1358 | 1359 | err_cleanup_filter: |
1359 | 1360 | if (ts->filter_cleanup) |
1360 | 1361 | |
... | ... | @@ -1383,8 +1384,13 @@ |
1383 | 1384 | regulator_disable(ts->reg); |
1384 | 1385 | regulator_put(ts->reg); |
1385 | 1386 | |
1386 | - if (ts->gpio_pendown != -1) | |
1387 | + if (!ts->get_pendown_state) { | |
1388 | + /* | |
1389 | + * If we are not using specialized pendown method we must | |
1390 | + * have been relying on gpio we set up ourselves. | |
1391 | + */ | |
1387 | 1392 | gpio_free(ts->gpio_pendown); |
1393 | + } | |
1388 | 1394 | |
1389 | 1395 | if (ts->filter_cleanup) |
1390 | 1396 | ts->filter_cleanup(ts->filter_data); |
drivers/input/touchscreen/wacom_w8001.c
... | ... | @@ -51,6 +51,10 @@ |
51 | 51 | #define W8001_PKTLEN_TPCCTL 11 /* control packet */ |
52 | 52 | #define W8001_PKTLEN_TOUCH2FG 13 |
53 | 53 | |
54 | +/* resolution in points/mm */ | |
55 | +#define W8001_PEN_RESOLUTION 100 | |
56 | +#define W8001_TOUCH_RESOLUTION 10 | |
57 | + | |
54 | 58 | struct w8001_coord { |
55 | 59 | u8 rdy; |
56 | 60 | u8 tsw; |
... | ... | @@ -198,7 +202,7 @@ |
198 | 202 | query->y = 1024; |
199 | 203 | if (query->panel_res) |
200 | 204 | query->x = query->y = (1 << query->panel_res); |
201 | - query->panel_res = 10; | |
205 | + query->panel_res = W8001_TOUCH_RESOLUTION; | |
202 | 206 | } |
203 | 207 | } |
204 | 208 | |
... | ... | @@ -394,6 +398,8 @@ |
394 | 398 | |
395 | 399 | input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); |
396 | 400 | input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); |
401 | + input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); | |
402 | + input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); | |
397 | 403 | input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); |
398 | 404 | if (coord.tilt_x && coord.tilt_y) { |
399 | 405 | input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); |
400 | 406 | |
401 | 407 | |
402 | 408 | |
... | ... | @@ -418,14 +424,17 @@ |
418 | 424 | w8001->max_touch_x = touch.x; |
419 | 425 | w8001->max_touch_y = touch.y; |
420 | 426 | |
421 | - /* scale to pen maximum */ | |
422 | 427 | if (w8001->max_pen_x && w8001->max_pen_y) { |
428 | + /* if pen is supported scale to pen maximum */ | |
423 | 429 | touch.x = w8001->max_pen_x; |
424 | 430 | touch.y = w8001->max_pen_y; |
431 | + touch.panel_res = W8001_PEN_RESOLUTION; | |
425 | 432 | } |
426 | 433 | |
427 | 434 | input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); |
428 | 435 | input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); |
436 | + input_abs_set_res(dev, ABS_X, touch.panel_res); | |
437 | + input_abs_set_res(dev, ABS_Y, touch.panel_res); | |
429 | 438 | |
430 | 439 | switch (touch.sensor_id) { |
431 | 440 | case 0: |
drivers/tty/sysrq.c
... | ... | @@ -571,6 +571,7 @@ |
571 | 571 | unsigned int alt_use; |
572 | 572 | bool active; |
573 | 573 | bool need_reinject; |
574 | + bool reinjecting; | |
574 | 575 | }; |
575 | 576 | |
576 | 577 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) |
... | ... | @@ -581,6 +582,10 @@ |
581 | 582 | unsigned int alt_code = sysrq->alt_use; |
582 | 583 | |
583 | 584 | if (sysrq->need_reinject) { |
585 | + /* we do not want the assignment to be reordered */ | |
586 | + sysrq->reinjecting = true; | |
587 | + mb(); | |
588 | + | |
584 | 589 | /* Simulate press and release of Alt + SysRq */ |
585 | 590 | input_inject_event(handle, EV_KEY, alt_code, 1); |
586 | 591 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); |
... | ... | @@ -589,6 +594,9 @@ |
589 | 594 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); |
590 | 595 | input_inject_event(handle, EV_KEY, alt_code, 0); |
591 | 596 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); |
597 | + | |
598 | + mb(); | |
599 | + sysrq->reinjecting = false; | |
592 | 600 | } |
593 | 601 | } |
594 | 602 | |
... | ... | @@ -599,6 +607,13 @@ |
599 | 607 | bool was_active = sysrq->active; |
600 | 608 | bool suppress; |
601 | 609 | |
610 | + /* | |
611 | + * Do not filter anything if we are in the process of re-injecting | |
612 | + * Alt+SysRq combination. | |
613 | + */ | |
614 | + if (sysrq->reinjecting) | |
615 | + return false; | |
616 | + | |
602 | 617 | switch (type) { |
603 | 618 | |
604 | 619 | case EV_SYN: |
... | ... | @@ -629,7 +644,7 @@ |
629 | 644 | sysrq->alt_use = sysrq->alt; |
630 | 645 | /* |
631 | 646 | * If nothing else will be pressed we'll need |
632 | - * to * re-inject Alt-SysRq keysroke. | |
647 | + * to re-inject Alt-SysRq keysroke. | |
633 | 648 | */ |
634 | 649 | sysrq->need_reinject = true; |
635 | 650 | } |
include/linux/input/matrix_keypad.h
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | #include <linux/types.h> |
5 | 5 | #include <linux/input.h> |
6 | 6 | |
7 | -#define MATRIX_MAX_ROWS 16 | |
8 | -#define MATRIX_MAX_COLS 16 | |
7 | +#define MATRIX_MAX_ROWS 32 | |
8 | +#define MATRIX_MAX_COLS 32 | |
9 | 9 | |
10 | 10 | #define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ |
11 | 11 | (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ |