aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-02-15 12:40:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-02-15 12:40:27 -0500
commit87450bd55d6f7caa472b5db49a97ca373baf2577 (patch)
tree00cc4e9da0e486c5d540c2f733a75a9230405f40
parent055d219441cc23f631240335fd369b6b5852681a (diff)
parentcfaea56741360311d0dabcb6603fa78c2e3de155 (diff)
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
-rw-r--r--drivers/input/input.c37
-rw-r--r--drivers/input/misc/rotary_encoder.c4
-rw-r--r--drivers/input/serio/serio.c11
-rw-r--r--drivers/input/tablet/wacom_sys.c2
-rw-r--r--drivers/input/touchscreen/ads7846.c38
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c13
-rw-r--r--drivers/tty/sysrq.c17
-rw-r--r--include/linux/input/matrix_keypad.h4
8 files changed, 72 insertions, 54 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7985114beac..11905b6a302 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -75,7 +75,6 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
75 * dev->event_lock held and interrupts disabled. 75 * dev->event_lock held and interrupts disabled.
76 */ 76 */
77static void input_pass_event(struct input_dev *dev, 77static void input_pass_event(struct input_dev *dev,
78 struct input_handler *src_handler,
79 unsigned int type, unsigned int code, int value) 78 unsigned int type, unsigned int code, int value)
80{ 79{
81 struct input_handler *handler; 80 struct input_handler *handler;
@@ -94,15 +93,6 @@ static void input_pass_event(struct input_dev *dev,
94 continue; 93 continue;
95 94
96 handler = handle->handler; 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 if (!handler->filter) { 96 if (!handler->filter) {
107 if (filtered) 97 if (filtered)
108 break; 98 break;
@@ -132,7 +122,7 @@ static void input_repeat_key(unsigned long data)
132 if (test_bit(dev->repeat_key, dev->key) && 122 if (test_bit(dev->repeat_key, dev->key) &&
133 is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { 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 if (dev->sync) { 127 if (dev->sync) {
138 /* 128 /*
@@ -141,7 +131,7 @@ static void input_repeat_key(unsigned long data)
141 * Otherwise assume that the driver will send 131 * Otherwise assume that the driver will send
142 * SYN_REPORT once it's done. 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 if (dev->rep[REP_PERIOD]) 137 if (dev->rep[REP_PERIOD])
@@ -174,7 +164,6 @@ static void input_stop_autorepeat(struct input_dev *dev)
174#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) 164#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
175 165
176static int input_handle_abs_event(struct input_dev *dev, 166static int input_handle_abs_event(struct input_dev *dev,
177 struct input_handler *src_handler,
178 unsigned int code, int *pval) 167 unsigned int code, int *pval)
179{ 168{
180 bool is_mt_event; 169 bool is_mt_event;
@@ -218,15 +207,13 @@ static int input_handle_abs_event(struct input_dev *dev,
218 /* Flush pending "slot" event */ 207 /* Flush pending "slot" event */
219 if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { 208 if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
220 input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); 209 input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
221 input_pass_event(dev, src_handler, 210 input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
222 EV_ABS, ABS_MT_SLOT, dev->slot);
223 } 211 }
224 212
225 return INPUT_PASS_TO_HANDLERS; 213 return INPUT_PASS_TO_HANDLERS;
226} 214}
227 215
228static void input_handle_event(struct input_dev *dev, 216static void input_handle_event(struct input_dev *dev,
229 struct input_handler *src_handler,
230 unsigned int type, unsigned int code, int value) 217 unsigned int type, unsigned int code, int value)
231{ 218{
232 int disposition = INPUT_IGNORE_EVENT; 219 int disposition = INPUT_IGNORE_EVENT;
@@ -279,8 +266,7 @@ static void input_handle_event(struct input_dev *dev,
279 266
280 case EV_ABS: 267 case EV_ABS:
281 if (is_event_supported(code, dev->absbit, ABS_MAX)) 268 if (is_event_supported(code, dev->absbit, ABS_MAX))
282 disposition = input_handle_abs_event(dev, src_handler, 269 disposition = input_handle_abs_event(dev, code, &value);
283 code, &value);
284 270
285 break; 271 break;
286 272
@@ -338,7 +324,7 @@ static void input_handle_event(struct input_dev *dev,
338 dev->event(dev, type, code, value); 324 dev->event(dev, type, code, value);
339 325
340 if (disposition & INPUT_PASS_TO_HANDLERS) 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 @@ void input_event(struct input_dev *dev,
367 353
368 spin_lock_irqsave(&dev->event_lock, flags); 354 spin_lock_irqsave(&dev->event_lock, flags);
369 add_input_randomness(type, code, value); 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 spin_unlock_irqrestore(&dev->event_lock, flags); 357 spin_unlock_irqrestore(&dev->event_lock, flags);
372 } 358 }
373} 359}
@@ -397,8 +383,7 @@ void input_inject_event(struct input_handle *handle,
397 rcu_read_lock(); 383 rcu_read_lock();
398 grab = rcu_dereference(dev->grab); 384 grab = rcu_dereference(dev->grab);
399 if (!grab || grab == handle) 385 if (!grab || grab == handle)
400 input_handle_event(dev, handle->handler, 386 input_handle_event(dev, type, code, value);
401 type, code, value);
402 rcu_read_unlock(); 387 rcu_read_unlock();
403 388
404 spin_unlock_irqrestore(&dev->event_lock, flags); 389 spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -611,10 +596,10 @@ static void input_dev_release_keys(struct input_dev *dev)
611 for (code = 0; code <= KEY_MAX; code++) { 596 for (code = 0; code <= KEY_MAX; code++) {
612 if (is_event_supported(code, dev->keybit, KEY_MAX) && 597 if (is_event_supported(code, dev->keybit, KEY_MAX) &&
613 __test_and_clear_bit(code, dev->key)) { 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
@@ -889,9 +874,9 @@ int input_set_keycode(struct input_dev *dev,
889 !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && 874 !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
890 __test_and_clear_bit(old_keycode, dev->key)) { 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 if (dev->sync) 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 out: 882 out:
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 1f8e0108962..7e64d01da2b 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
176 176
177 /* request the IRQs */ 177 /* request the IRQs */
178 err = request_irq(encoder->irq_a, &rotary_encoder_irq, 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 DRV_NAME, encoder); 180 DRV_NAME, encoder);
181 if (err) { 181 if (err) {
182 dev_err(&pdev->dev, "unable to request IRQ %d\n", 182 dev_err(&pdev->dev, "unable to request IRQ %d\n",
@@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
185 } 185 }
186 186
187 err = request_irq(encoder->irq_b, &rotary_encoder_irq, 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 DRV_NAME, encoder); 189 DRV_NAME, encoder);
190 if (err) { 190 if (err) {
191 dev_err(&pdev->dev, "unable to request IRQ %d\n", 191 dev_err(&pdev->dev, "unable to request IRQ %d\n",
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index db5b0bca1a1..7c38d1fbabf 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -188,7 +188,8 @@ static void serio_free_event(struct serio_event *event)
188 kfree(event); 188 kfree(event);
189} 189}
190 190
191static void serio_remove_duplicate_events(struct serio_event *event) 191static void serio_remove_duplicate_events(void *object,
192 enum serio_event_type type)
192{ 193{
193 struct serio_event *e, *next; 194 struct serio_event *e, *next;
194 unsigned long flags; 195 unsigned long flags;
@@ -196,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event)
196 spin_lock_irqsave(&serio_event_lock, flags); 197 spin_lock_irqsave(&serio_event_lock, flags);
197 198
198 list_for_each_entry_safe(e, next, &serio_event_list, node) { 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 * If this event is of different type we should not 202 * If this event is of different type we should not
202 * look further - we only suppress duplicate events 203 * look further - we only suppress duplicate events
203 * that were sent back-to-back. 204 * that were sent back-to-back.
204 */ 205 */
205 if (event->type != e->type) 206 if (type != e->type)
206 break; 207 break;
207 208
208 list_del_init(&e->node); 209 list_del_init(&e->node);
@@ -245,7 +246,7 @@ static void serio_handle_event(struct work_struct *work)
245 break; 246 break;
246 } 247 }
247 248
248 serio_remove_duplicate_events(event); 249 serio_remove_duplicate_events(event->object, event->type);
249 serio_free_event(event); 250 serio_free_event(event);
250 } 251 }
251 252
@@ -436,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
436 } else if (!strncmp(buf, "rescan", count)) { 437 } else if (!strncmp(buf, "rescan", count)) {
437 serio_disconnect_port(serio); 438 serio_disconnect_port(serio);
438 serio_find_driver(serio); 439 serio_find_driver(serio);
440 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
439 } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { 441 } else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
440 serio_disconnect_port(serio); 442 serio_disconnect_port(serio);
441 error = serio_bind_driver(serio, to_serio_driver(drv)); 443 error = serio_bind_driver(serio, to_serio_driver(drv));
442 put_driver(drv); 444 put_driver(drv);
445 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
443 } else { 446 } else {
444 error = -EINVAL; 447 error = -EINVAL;
445 } 448 }
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index fc381498b79..cf8fb9f5d4a 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
519 /* Retrieve the physical and logical size for OEM devices */ 519 /* Retrieve the physical and logical size for OEM devices */
520 error = wacom_retrieve_hid_descriptor(intf, features); 520 error = wacom_retrieve_hid_descriptor(intf, features);
521 if (error) 521 if (error)
522 goto fail2; 522 goto fail3;
523 523
524 wacom_setup_device_quirks(features); 524 wacom_setup_device_quirks(features);
525 525
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 14ea54b78e4..4bf2316e328 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -941,28 +941,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
941 struct ads7846_platform_data *pdata = spi->dev.platform_data; 941 struct ads7846_platform_data *pdata = spi->dev.platform_data;
942 int err; 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 * reason the touchscreen isn't hooked up, we don't need to access 946 * reason the touchscreen isn't hooked up, we don't need to access
946 * the pendown state. 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 if (pdata->get_pendown_state) { 950 if (pdata->get_pendown_state) {
954 ts->get_pendown_state = pdata->get_pendown_state; 951 ts->get_pendown_state = pdata->get_pendown_state;
955 return 0; 952 } else if (gpio_is_valid(pdata->gpio_pendown)) {
956 }
957 953
958 err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); 954 err = gpio_request(pdata->gpio_pendown, "ads7846_pendown");
959 if (err) { 955 if (err) {
960 dev_err(&spi->dev, "failed to request pendown GPIO%d\n", 956 dev_err(&spi->dev, "failed to request pendown GPIO%d\n",
961 pdata->gpio_pendown); 957 pdata->gpio_pendown);
962 return err; 958 return err;
963 } 959 }
964 960
965 ts->gpio_pendown = pdata->gpio_pendown; 961 ts->gpio_pendown = pdata->gpio_pendown;
962
963 } else {
964 dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
965 return -EINVAL;
966 }
966 967
967 return 0; 968 return 0;
968} 969}
@@ -1353,7 +1354,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1353 err_put_regulator: 1354 err_put_regulator:
1354 regulator_put(ts->reg); 1355 regulator_put(ts->reg);
1355 err_free_gpio: 1356 err_free_gpio:
1356 if (ts->gpio_pendown != -1) 1357 if (!ts->get_pendown_state)
1357 gpio_free(ts->gpio_pendown); 1358 gpio_free(ts->gpio_pendown);
1358 err_cleanup_filter: 1359 err_cleanup_filter:
1359 if (ts->filter_cleanup) 1360 if (ts->filter_cleanup)
@@ -1383,8 +1384,13 @@ static int __devexit ads7846_remove(struct spi_device *spi)
1383 regulator_disable(ts->reg); 1384 regulator_disable(ts->reg);
1384 regulator_put(ts->reg); 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 gpio_free(ts->gpio_pendown); 1392 gpio_free(ts->gpio_pendown);
1393 }
1388 1394
1389 if (ts->filter_cleanup) 1395 if (ts->filter_cleanup)
1390 ts->filter_cleanup(ts->filter_data); 1396 ts->filter_cleanup(ts->filter_data);
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 5cb8449c909..c14412ef464 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -51,6 +51,10 @@ MODULE_LICENSE("GPL");
51#define W8001_PKTLEN_TPCCTL 11 /* control packet */ 51#define W8001_PKTLEN_TPCCTL 11 /* control packet */
52#define W8001_PKTLEN_TOUCH2FG 13 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
54struct w8001_coord { 58struct w8001_coord {
55 u8 rdy; 59 u8 rdy;
56 u8 tsw; 60 u8 tsw;
@@ -198,7 +202,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
198 query->y = 1024; 202 query->y = 1024;
199 if (query->panel_res) 203 if (query->panel_res)
200 query->x = query->y = (1 << query->panel_res); 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 @@ static int w8001_setup(struct w8001 *w8001)
394 398
395 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); 399 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
396 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); 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 input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); 403 input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0);
398 if (coord.tilt_x && coord.tilt_y) { 404 if (coord.tilt_x && coord.tilt_y) {
399 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); 405 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
@@ -418,14 +424,17 @@ static int w8001_setup(struct w8001 *w8001)
418 w8001->max_touch_x = touch.x; 424 w8001->max_touch_x = touch.x;
419 w8001->max_touch_y = touch.y; 425 w8001->max_touch_y = touch.y;
420 426
421 /* scale to pen maximum */
422 if (w8001->max_pen_x && w8001->max_pen_y) { 427 if (w8001->max_pen_x && w8001->max_pen_y) {
428 /* if pen is supported scale to pen maximum */
423 touch.x = w8001->max_pen_x; 429 touch.x = w8001->max_pen_x;
424 touch.y = w8001->max_pen_y; 430 touch.y = w8001->max_pen_y;
431 touch.panel_res = W8001_PEN_RESOLUTION;
425 } 432 }
426 433
427 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); 434 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
428 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); 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 switch (touch.sensor_id) { 439 switch (touch.sensor_id) {
431 case 0: 440 case 0:
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 8e0dd254eb1..81f13958e75 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -571,6 +571,7 @@ struct sysrq_state {
571 unsigned int alt_use; 571 unsigned int alt_use;
572 bool active; 572 bool active;
573 bool need_reinject; 573 bool need_reinject;
574 bool reinjecting;
574}; 575};
575 576
576static void sysrq_reinject_alt_sysrq(struct work_struct *work) 577static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
581 unsigned int alt_code = sysrq->alt_use; 582 unsigned int alt_code = sysrq->alt_use;
582 583
583 if (sysrq->need_reinject) { 584 if (sysrq->need_reinject) {
585 /* we do not want the assignment to be reordered */
586 sysrq->reinjecting = true;
587 mb();
588
584 /* Simulate press and release of Alt + SysRq */ 589 /* Simulate press and release of Alt + SysRq */
585 input_inject_event(handle, EV_KEY, alt_code, 1); 590 input_inject_event(handle, EV_KEY, alt_code, 1);
586 input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); 591 input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
@@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work)
589 input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); 594 input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
590 input_inject_event(handle, EV_KEY, alt_code, 0); 595 input_inject_event(handle, EV_KEY, alt_code, 0);
591 input_inject_event(handle, EV_SYN, SYN_REPORT, 1); 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 @@ static bool sysrq_filter(struct input_handle *handle,
599 bool was_active = sysrq->active; 607 bool was_active = sysrq->active;
600 bool suppress; 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 switch (type) { 617 switch (type) {
603 618
604 case EV_SYN: 619 case EV_SYN:
@@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_handle *handle,
629 sysrq->alt_use = sysrq->alt; 644 sysrq->alt_use = sysrq->alt;
630 /* 645 /*
631 * If nothing else will be pressed we'll need 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 sysrq->need_reinject = true; 649 sysrq->need_reinject = true;
635 } 650 }
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 69747469174..fe7c4b9ae27 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -4,8 +4,8 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/input.h> 5#include <linux/input.h>
6 6
7#define MATRIX_MAX_ROWS 16 7#define MATRIX_MAX_ROWS 32
8#define MATRIX_MAX_COLS 16 8#define MATRIX_MAX_COLS 32
9 9
10#define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ 10#define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
11 (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ 11 (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\