aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-04-18 16:29:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-04-18 16:29:03 -0400
commit96fd2d57b8252e16dfacf8941f7a74a6119197f5 (patch)
tree095269c51def85fa1be27bb20ec8e562bdc5a564 /drivers
parent8a83f33100c691f5a576dba259cc05502dc358f0 (diff)
parentc36b58e8a9112017c2bcc322cc98e71241814303 (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: xen-kbdfront - fix mouse getting stuck after save/restore Input: estimate number of events per packet Input: evdev - indicate buffer overrun with SYN_DROPPED Input: document event types and codes and their intended use Input: add KEY_IMAGES specifically for AL Image Browser Input: twl4030_keypad - fix potential NULL dereference in twl4030_kp_probe() Input: h3600_ts - fix error handling at connect Input: twl4030_keypad - avoid potential NULL-pointer dereference
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/evdev.c33
-rw-r--r--drivers/input/input.c40
-rw-r--r--drivers/input/keyboard/twl4030_keypad.c6
-rw-r--r--drivers/input/misc/xen-kbdfront.c13
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c17
5 files changed, 87 insertions, 22 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 7f42d3a454d2..88d8e4cb419a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -39,13 +39,13 @@ struct evdev {
39}; 39};
40 40
41struct evdev_client { 41struct evdev_client {
42 int head; 42 unsigned int head;
43 int tail; 43 unsigned int tail;
44 spinlock_t buffer_lock; /* protects access to buffer, head and tail */ 44 spinlock_t buffer_lock; /* protects access to buffer, head and tail */
45 struct fasync_struct *fasync; 45 struct fasync_struct *fasync;
46 struct evdev *evdev; 46 struct evdev *evdev;
47 struct list_head node; 47 struct list_head node;
48 int bufsize; 48 unsigned int bufsize;
49 struct input_event buffer[]; 49 struct input_event buffer[];
50}; 50};
51 51
@@ -55,16 +55,25 @@ static DEFINE_MUTEX(evdev_table_mutex);
55static void evdev_pass_event(struct evdev_client *client, 55static void evdev_pass_event(struct evdev_client *client,
56 struct input_event *event) 56 struct input_event *event)
57{ 57{
58 /* 58 /* Interrupts are disabled, just acquire the lock. */
59 * Interrupts are disabled, just acquire the lock.
60 * Make sure we don't leave with the client buffer
61 * "empty" by having client->head == client->tail.
62 */
63 spin_lock(&client->buffer_lock); 59 spin_lock(&client->buffer_lock);
64 do { 60
65 client->buffer[client->head++] = *event; 61 client->buffer[client->head++] = *event;
66 client->head &= client->bufsize - 1; 62 client->head &= client->bufsize - 1;
67 } while (client->head == client->tail); 63
64 if (unlikely(client->head == client->tail)) {
65 /*
66 * This effectively "drops" all unconsumed events, leaving
67 * EV_SYN/SYN_DROPPED plus the newest event in the queue.
68 */
69 client->tail = (client->head - 2) & (client->bufsize - 1);
70
71 client->buffer[client->tail].time = event->time;
72 client->buffer[client->tail].type = EV_SYN;
73 client->buffer[client->tail].code = SYN_DROPPED;
74 client->buffer[client->tail].value = 0;
75 }
76
68 spin_unlock(&client->buffer_lock); 77 spin_unlock(&client->buffer_lock);
69 78
70 if (event->type == EV_SYN) 79 if (event->type == EV_SYN)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index d6e8bd8a851c..ebbceedc92f4 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1746,6 +1746,42 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
1746} 1746}
1747EXPORT_SYMBOL(input_set_capability); 1747EXPORT_SYMBOL(input_set_capability);
1748 1748
1749static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
1750{
1751 int mt_slots;
1752 int i;
1753 unsigned int events;
1754
1755 if (dev->mtsize) {
1756 mt_slots = dev->mtsize;
1757 } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
1758 mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
1759 dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
1760 clamp(mt_slots, 2, 32);
1761 } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
1762 mt_slots = 2;
1763 } else {
1764 mt_slots = 0;
1765 }
1766
1767 events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
1768
1769 for (i = 0; i < ABS_CNT; i++) {
1770 if (test_bit(i, dev->absbit)) {
1771 if (input_is_mt_axis(i))
1772 events += mt_slots;
1773 else
1774 events++;
1775 }
1776 }
1777
1778 for (i = 0; i < REL_CNT; i++)
1779 if (test_bit(i, dev->relbit))
1780 events++;
1781
1782 return events;
1783}
1784
1749#define INPUT_CLEANSE_BITMASK(dev, type, bits) \ 1785#define INPUT_CLEANSE_BITMASK(dev, type, bits) \
1750 do { \ 1786 do { \
1751 if (!test_bit(EV_##type, dev->evbit)) \ 1787 if (!test_bit(EV_##type, dev->evbit)) \
@@ -1793,6 +1829,10 @@ int input_register_device(struct input_dev *dev)
1793 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ 1829 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
1794 input_cleanse_bitmasks(dev); 1830 input_cleanse_bitmasks(dev);
1795 1831
1832 if (!dev->hint_events_per_packet)
1833 dev->hint_events_per_packet =
1834 input_estimate_events_per_packet(dev);
1835
1796 /* 1836 /*
1797 * If delay and period are pre-set by the driver, then autorepeating 1837 * If delay and period are pre-set by the driver, then autorepeating
1798 * is handled by the driver itself and we don't do it in input.c. 1838 * is handled by the driver itself and we don't do it in input.c.
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
index 09bef79d9da1..a26922cf0e84 100644
--- a/drivers/input/keyboard/twl4030_keypad.c
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -332,18 +332,20 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
332static int __devinit twl4030_kp_probe(struct platform_device *pdev) 332static int __devinit twl4030_kp_probe(struct platform_device *pdev)
333{ 333{
334 struct twl4030_keypad_data *pdata = pdev->dev.platform_data; 334 struct twl4030_keypad_data *pdata = pdev->dev.platform_data;
335 const struct matrix_keymap_data *keymap_data = pdata->keymap_data; 335 const struct matrix_keymap_data *keymap_data;
336 struct twl4030_keypad *kp; 336 struct twl4030_keypad *kp;
337 struct input_dev *input; 337 struct input_dev *input;
338 u8 reg; 338 u8 reg;
339 int error; 339 int error;
340 340
341 if (!pdata || !pdata->rows || !pdata->cols || 341 if (!pdata || !pdata->rows || !pdata->cols || !pdata->keymap_data ||
342 pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { 342 pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) {
343 dev_err(&pdev->dev, "Invalid platform_data\n"); 343 dev_err(&pdev->dev, "Invalid platform_data\n");
344 return -EINVAL; 344 return -EINVAL;
345 } 345 }
346 346
347 keymap_data = pdata->keymap_data;
348
347 kp = kzalloc(sizeof(*kp), GFP_KERNEL); 349 kp = kzalloc(sizeof(*kp), GFP_KERNEL);
348 input = input_allocate_device(); 350 input = input_allocate_device();
349 if (!kp || !input) { 351 if (!kp || !input) {
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 7077f9bf5ead..62bae99424e6 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -303,7 +303,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
303 enum xenbus_state backend_state) 303 enum xenbus_state backend_state)
304{ 304{
305 struct xenkbd_info *info = dev_get_drvdata(&dev->dev); 305 struct xenkbd_info *info = dev_get_drvdata(&dev->dev);
306 int val; 306 int ret, val;
307 307
308 switch (backend_state) { 308 switch (backend_state) {
309 case XenbusStateInitialising: 309 case XenbusStateInitialising:
@@ -316,6 +316,17 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
316 316
317 case XenbusStateInitWait: 317 case XenbusStateInitWait:
318InitWait: 318InitWait:
319 ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend,
320 "feature-abs-pointer", "%d", &val);
321 if (ret < 0)
322 val = 0;
323 if (val) {
324 ret = xenbus_printf(XBT_NIL, info->xbdev->nodename,
325 "request-abs-pointer", "1");
326 if (ret)
327 pr_warning("xenkbd: can't request abs-pointer");
328 }
329
319 xenbus_switch_state(dev, XenbusStateConnected); 330 xenbus_switch_state(dev, XenbusStateConnected);
320 break; 331 break;
321 332
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index efa06882de00..45f93d0f5592 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -399,31 +399,34 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
399 IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { 399 IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) {
400 printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); 400 printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
401 err = -EBUSY; 401 err = -EBUSY;
402 goto fail2; 402 goto fail1;
403 } 403 }
404 404
405 if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, 405 if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
406 IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { 406 IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) {
407 printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); 407 printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
408 err = -EBUSY; 408 err = -EBUSY;
409 goto fail3; 409 goto fail2;
410 } 410 }
411 411
412 serio_set_drvdata(serio, ts); 412 serio_set_drvdata(serio, ts);
413 413
414 err = serio_open(serio, drv); 414 err = serio_open(serio, drv);
415 if (err) 415 if (err)
416 return err; 416 goto fail3;
417 417
418 //h3600_flite_control(1, 25); /* default brightness */ 418 //h3600_flite_control(1, 25); /* default brightness */
419 input_register_device(ts->dev); 419 err = input_register_device(ts->dev);
420 if (err)
421 goto fail4;
420 422
421 return 0; 423 return 0;
422 424
423fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); 425fail4: serio_close(serio);
426fail3: serio_set_drvdata(serio, NULL);
427 free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
424fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); 428fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
425fail1: serio_set_drvdata(serio, NULL); 429fail1: input_free_device(input_dev);
426 input_free_device(input_dev);
427 kfree(ts); 430 kfree(ts);
428 return err; 431 return err;
429} 432}