diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index ec3db3ade118..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 | ||
@@ -132,6 +149,11 @@ static void input_start_autorepeat(struct input_dev *dev, int code) | |||
132 | } | 149 | } |
133 | } | 150 | } |
134 | 151 | ||
152 | static void input_stop_autorepeat(struct input_dev *dev) | ||
153 | { | ||
154 | del_timer(&dev->timer); | ||
155 | } | ||
156 | |||
135 | #define INPUT_IGNORE_EVENT 0 | 157 | #define INPUT_IGNORE_EVENT 0 |
136 | #define INPUT_PASS_TO_HANDLERS 1 | 158 | #define INPUT_PASS_TO_HANDLERS 1 |
137 | #define INPUT_PASS_TO_DEVICE 2 | 159 | #define INPUT_PASS_TO_DEVICE 2 |
@@ -156,6 +178,10 @@ static void input_handle_event(struct input_dev *dev, | |||
156 | disposition = INPUT_PASS_TO_HANDLERS; | 178 | disposition = INPUT_PASS_TO_HANDLERS; |
157 | } | 179 | } |
158 | break; | 180 | break; |
181 | case SYN_MT_REPORT: | ||
182 | dev->sync = 0; | ||
183 | disposition = INPUT_PASS_TO_HANDLERS; | ||
184 | break; | ||
159 | } | 185 | } |
160 | break; | 186 | break; |
161 | 187 | ||
@@ -167,6 +193,8 @@ static void input_handle_event(struct input_dev *dev, | |||
167 | __change_bit(code, dev->key); | 193 | __change_bit(code, dev->key); |
168 | if (value) | 194 | if (value) |
169 | input_start_autorepeat(dev, code); | 195 | input_start_autorepeat(dev, code); |
196 | else | ||
197 | input_stop_autorepeat(dev); | ||
170 | } | 198 | } |
171 | 199 | ||
172 | disposition = INPUT_PASS_TO_HANDLERS; | 200 | disposition = INPUT_PASS_TO_HANDLERS; |
@@ -185,6 +213,11 @@ static void input_handle_event(struct input_dev *dev, | |||
185 | case EV_ABS: | 213 | case EV_ABS: |
186 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { | 214 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { |
187 | 215 | ||
216 | if (test_bit(code, input_abs_bypass)) { | ||
217 | disposition = INPUT_PASS_TO_HANDLERS; | ||
218 | break; | ||
219 | } | ||
220 | |||
188 | value = input_defuzz_abs_event(value, | 221 | value = input_defuzz_abs_event(value, |
189 | dev->abs[code], dev->absfuzz[code]); | 222 | dev->abs[code], dev->absfuzz[code]); |
190 | 223 | ||
@@ -737,11 +770,11 @@ static inline void input_wakeup_procfs_readers(void) | |||
737 | 770 | ||
738 | static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) | 771 | static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait) |
739 | { | 772 | { |
740 | int state = input_devices_state; | ||
741 | |||
742 | poll_wait(file, &input_devices_poll_wait, wait); | 773 | poll_wait(file, &input_devices_poll_wait, wait); |
743 | if (state != input_devices_state) | 774 | if (file->f_version != input_devices_state) { |
775 | file->f_version = input_devices_state; | ||
744 | return POLLIN | POLLRDNORM; | 776 | return POLLIN | POLLRDNORM; |
777 | } | ||
745 | 778 | ||
746 | return 0; | 779 | return 0; |
747 | } | 780 | } |
@@ -1542,7 +1575,6 @@ int input_register_handle(struct input_handle *handle) | |||
1542 | return error; | 1575 | return error; |
1543 | list_add_tail_rcu(&handle->d_node, &dev->h_list); | 1576 | list_add_tail_rcu(&handle->d_node, &dev->h_list); |
1544 | mutex_unlock(&dev->mutex); | 1577 | mutex_unlock(&dev->mutex); |
1545 | synchronize_rcu(); | ||
1546 | 1578 | ||
1547 | /* | 1579 | /* |
1548 | * Since we are supposed to be called from ->connect() | 1580 | * Since we are supposed to be called from ->connect() |
@@ -1628,10 +1660,20 @@ static const struct file_operations input_fops = { | |||
1628 | .open = input_open_file, | 1660 | .open = input_open_file, |
1629 | }; | 1661 | }; |
1630 | 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 | |||
1631 | static int __init input_init(void) | 1671 | static int __init input_init(void) |
1632 | { | 1672 | { |
1633 | int err; | 1673 | int err; |
1634 | 1674 | ||
1675 | input_init_abs_bypass(); | ||
1676 | |||
1635 | err = class_register(&input_class); | 1677 | err = class_register(&input_class); |
1636 | if (err) { | 1678 | if (err) { |
1637 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 1679 | printk(KERN_ERR "input: unable to register input_dev class\n"); |