diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index d44065d2e662..e54e002665b0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -29,6 +29,23 @@ MODULE_LICENSE("GPL"); | |||
29 | 29 | ||
30 | #define INPUT_DEVICES 256 | 30 | #define INPUT_DEVICES 256 |
31 | 31 | ||
32 | /* | ||
33 | * EV_ABS events which should not be cached are listed here. | ||
34 | */ | ||
35 | static unsigned int input_abs_bypass_init_data[] __initdata = { | ||
36 | ABS_MT_TOUCH_MAJOR, | ||
37 | ABS_MT_TOUCH_MINOR, | ||
38 | ABS_MT_WIDTH_MAJOR, | ||
39 | ABS_MT_WIDTH_MINOR, | ||
40 | ABS_MT_ORIENTATION, | ||
41 | ABS_MT_POSITION_X, | ||
42 | ABS_MT_POSITION_Y, | ||
43 | ABS_MT_TOOL_TYPE, | ||
44 | ABS_MT_BLOB_ID, | ||
45 | 0 | ||
46 | }; | ||
47 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; | ||
48 | |||
32 | static LIST_HEAD(input_dev_list); | 49 | static LIST_HEAD(input_dev_list); |
33 | static LIST_HEAD(input_handler_list); | 50 | static LIST_HEAD(input_handler_list); |
34 | 51 | ||
@@ -161,6 +178,10 @@ static void input_handle_event(struct input_dev *dev, | |||
161 | disposition = INPUT_PASS_TO_HANDLERS; | 178 | disposition = INPUT_PASS_TO_HANDLERS; |
162 | } | 179 | } |
163 | break; | 180 | break; |
181 | case SYN_MT_REPORT: | ||
182 | dev->sync = 0; | ||
183 | disposition = INPUT_PASS_TO_HANDLERS; | ||
184 | break; | ||
164 | } | 185 | } |
165 | break; | 186 | break; |
166 | 187 | ||
@@ -192,6 +213,11 @@ static void input_handle_event(struct input_dev *dev, | |||
192 | case EV_ABS: | 213 | case EV_ABS: |
193 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { | 214 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { |
194 | 215 | ||
216 | if (test_bit(code, input_abs_bypass)) { | ||
217 | disposition = INPUT_PASS_TO_HANDLERS; | ||
218 | break; | ||
219 | } | ||
220 | |||
195 | value = input_defuzz_abs_event(value, | 221 | value = input_defuzz_abs_event(value, |
196 | dev->abs[code], dev->absfuzz[code]); | 222 | dev->abs[code], dev->absfuzz[code]); |
197 | 223 | ||
@@ -1549,7 +1575,6 @@ int input_register_handle(struct input_handle *handle) | |||
1549 | return error; | 1575 | return error; |
1550 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1576 | list_add_tail_rcu(&handle->d_node, &dev->h_list); |
1551 | mutex_unlock(&dev->mutex); | 1577 | mutex_unlock(&dev->mutex); |
1552 | synchronize_rcu(); | ||
1553 | 1578 | ||
1554 | /* | 1579 | /* |
1555 | * Since we are supposed to be called from ->connect() | 1580 | * Since we are supposed to be called from ->connect() |
@@ -1635,10 +1660,20 @@ static const struct file_operations input_fops = { | |||
1635 | .open = input_open_file, | 1660 | .open = input_open_file, |
1636 | }; | 1661 | }; |
1637 | 1662 | ||
1663 | static void __init input_init_abs_bypass(void) | ||
1664 | { | ||
1665 | const unsigned int *p; | ||
1666 | |||
1667 | for (p = input_abs_bypass_init_data; *p; p++) | ||
1668 | input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p); | ||
1669 | } | ||
1670 | |||
1638 | static int __init input_init(void) | 1671 | static int __init input_init(void) |
1639 | { | 1672 | { |
1640 | int err; | 1673 | int err; |
1641 | 1674 | ||
1675 | input_init_abs_bypass(); | ||
1676 | |||
1642 | err = class_register(&input_class); | 1677 | err = class_register(&input_class); |
1643 | if (err) { | 1678 | if (err) { |
1644 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 1679 | printk(KERN_ERR "input: unable to register input_dev class\n"); |