diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-11 13:08:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-11 13:08:36 -0400 |
commit | c8c16e3624ec9e2b36b76b34266c5064ec7e5f98 (patch) | |
tree | ad31e485883a3ccfe5c51ce30c4e807487184bbd | |
parent | 584f1adaf069074f49b05da92f05995f8562206d (diff) | |
parent | a80d8b02751060a178bb1f7a6b7a93645a7a308b (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"An update to Synaptics PS/2 driver to handle "ForcePads" (currently
found in HP EliteBook 1040 laptops), a change for Elan PS/2 driver to
detect newer touchpads, bunch of devices get annotated as Trackpoint
and/or Pointer to help userspace classify and handle them, plus
assorted driver fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: serport - add compat handling for SPIOCSTYPE ioctl
Input: atmel_mxt_ts - fix double free of input device
Input: synaptics - add support for ForcePads
Input: matrix_keypad - use request_any_context_irq()
Input: atmel_mxt_ts - downgrade warning about empty interrupts
Input: wm971x - fix typo in module parameter description
Input: cap1106 - fix register definition
Input: add missing POINTER / DIRECT properties to a bunch of drivers
Input: add INPUT_PROP_POINTING_STICK property
Input: elantech - fix detection of touchpad on ASUS s301l
-rw-r--r-- | drivers/input/keyboard/cap1106.c | 4 | ||||
-rw-r--r-- | drivers/input/keyboard/matrix_keypad.c | 9 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 11 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 68 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 11 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics_usb.c | 6 | ||||
-rw-r--r-- | drivers/input/mouse/trackpoint.c | 3 | ||||
-rw-r--r-- | drivers/input/serio/serport.c | 45 | ||||
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 25 | ||||
-rw-r--r-- | drivers/input/touchscreen/wm9712.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/wm9713.c | 2 | ||||
-rw-r--r-- | include/uapi/linux/input.h | 1 |
14 files changed, 156 insertions, 37 deletions
diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c index 180b184ab90f..d70b65a14ced 100644 --- a/drivers/input/keyboard/cap1106.c +++ b/drivers/input/keyboard/cap1106.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #define CAP1106_REG_SENSOR_CONFIG 0x22 | 33 | #define CAP1106_REG_SENSOR_CONFIG 0x22 |
34 | #define CAP1106_REG_SENSOR_CONFIG2 0x23 | 34 | #define CAP1106_REG_SENSOR_CONFIG2 0x23 |
35 | #define CAP1106_REG_SAMPLING_CONFIG 0x24 | 35 | #define CAP1106_REG_SAMPLING_CONFIG 0x24 |
36 | #define CAP1106_REG_CALIBRATION 0x25 | 36 | #define CAP1106_REG_CALIBRATION 0x26 |
37 | #define CAP1106_REG_INT_ENABLE 0x26 | 37 | #define CAP1106_REG_INT_ENABLE 0x27 |
38 | #define CAP1106_REG_REPEAT_RATE 0x28 | 38 | #define CAP1106_REG_REPEAT_RATE 0x28 |
39 | #define CAP1106_REG_MT_CONFIG 0x2a | 39 | #define CAP1106_REG_MT_CONFIG 0x2a |
40 | #define CAP1106_REG_MT_PATTERN_CONFIG 0x2b | 40 | #define CAP1106_REG_MT_PATTERN_CONFIG 0x2b |
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 8d2e19e81e1e..e651fa692afe 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
@@ -332,23 +332,24 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev, | |||
332 | } | 332 | } |
333 | 333 | ||
334 | if (pdata->clustered_irq > 0) { | 334 | if (pdata->clustered_irq > 0) { |
335 | err = request_irq(pdata->clustered_irq, | 335 | err = request_any_context_irq(pdata->clustered_irq, |
336 | matrix_keypad_interrupt, | 336 | matrix_keypad_interrupt, |
337 | pdata->clustered_irq_flags, | 337 | pdata->clustered_irq_flags, |
338 | "matrix-keypad", keypad); | 338 | "matrix-keypad", keypad); |
339 | if (err) { | 339 | if (err < 0) { |
340 | dev_err(&pdev->dev, | 340 | dev_err(&pdev->dev, |
341 | "Unable to acquire clustered interrupt\n"); | 341 | "Unable to acquire clustered interrupt\n"); |
342 | goto err_free_rows; | 342 | goto err_free_rows; |
343 | } | 343 | } |
344 | } else { | 344 | } else { |
345 | for (i = 0; i < pdata->num_row_gpios; i++) { | 345 | for (i = 0; i < pdata->num_row_gpios; i++) { |
346 | err = request_irq(gpio_to_irq(pdata->row_gpios[i]), | 346 | err = request_any_context_irq( |
347 | gpio_to_irq(pdata->row_gpios[i]), | ||
347 | matrix_keypad_interrupt, | 348 | matrix_keypad_interrupt, |
348 | IRQF_TRIGGER_RISING | | 349 | IRQF_TRIGGER_RISING | |
349 | IRQF_TRIGGER_FALLING, | 350 | IRQF_TRIGGER_FALLING, |
350 | "matrix-keypad", keypad); | 351 | "matrix-keypad", keypad); |
351 | if (err) { | 352 | if (err < 0) { |
352 | dev_err(&pdev->dev, | 353 | dev_err(&pdev->dev, |
353 | "Unable to acquire interrupt for GPIO line %i\n", | 354 | "Unable to acquire interrupt for GPIO line %i\n", |
354 | pdata->row_gpios[i]); | 355 | pdata->row_gpios[i]); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a956b980ee73..35a49bf57227 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -2373,6 +2373,10 @@ int alps_init(struct psmouse *psmouse) | |||
2373 | dev2->keybit[BIT_WORD(BTN_LEFT)] = | 2373 | dev2->keybit[BIT_WORD(BTN_LEFT)] = |
2374 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); | 2374 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); |
2375 | 2375 | ||
2376 | __set_bit(INPUT_PROP_POINTER, dev2->propbit); | ||
2377 | if (priv->flags & ALPS_DUALPOINT) | ||
2378 | __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit); | ||
2379 | |||
2376 | if (input_register_device(priv->dev2)) | 2380 | if (input_register_device(priv->dev2)) |
2377 | goto init_fail; | 2381 | goto init_fail; |
2378 | 2382 | ||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index da51738eb59e..06fc6e76ffbe 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1331,6 +1331,13 @@ static bool elantech_is_signature_valid(const unsigned char *param) | |||
1331 | if (param[1] == 0) | 1331 | if (param[1] == 0) |
1332 | return true; | 1332 | return true; |
1333 | 1333 | ||
1334 | /* | ||
1335 | * Some models have a revision higher then 20. Meaning param[2] may | ||
1336 | * be 10 or 20, skip the rates check for these. | ||
1337 | */ | ||
1338 | if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) | ||
1339 | return true; | ||
1340 | |||
1334 | for (i = 0; i < ARRAY_SIZE(rates); i++) | 1341 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
1335 | if (param[2] == rates[i]) | 1342 | if (param[2] == rates[i]) |
1336 | return false; | 1343 | return false; |
@@ -1607,6 +1614,10 @@ int elantech_init(struct psmouse *psmouse) | |||
1607 | tp_dev->keybit[BIT_WORD(BTN_LEFT)] = | 1614 | tp_dev->keybit[BIT_WORD(BTN_LEFT)] = |
1608 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | | 1615 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | |
1609 | BIT_MASK(BTN_RIGHT); | 1616 | BIT_MASK(BTN_RIGHT); |
1617 | |||
1618 | __set_bit(INPUT_PROP_POINTER, tp_dev->propbit); | ||
1619 | __set_bit(INPUT_PROP_POINTING_STICK, tp_dev->propbit); | ||
1620 | |||
1610 | error = input_register_device(etd->tp_dev); | 1621 | error = input_register_device(etd->tp_dev); |
1611 | if (error < 0) | 1622 | if (error < 0) |
1612 | goto init_fail_tp_reg; | 1623 | goto init_fail_tp_reg; |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cff065f6261c..b4e1f014ddc2 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -670,6 +670,8 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) | |||
670 | __set_bit(REL_X, input_dev->relbit); | 670 | __set_bit(REL_X, input_dev->relbit); |
671 | __set_bit(REL_Y, input_dev->relbit); | 671 | __set_bit(REL_Y, input_dev->relbit); |
672 | 672 | ||
673 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
674 | |||
673 | psmouse->set_rate = psmouse_set_rate; | 675 | psmouse->set_rate = psmouse_set_rate; |
674 | psmouse->set_resolution = psmouse_set_resolution; | 676 | psmouse->set_resolution = psmouse_set_resolution; |
675 | psmouse->poll = psmouse_poll; | 677 | psmouse->poll = psmouse_poll; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index e8573c68f77e..fd23181c1fb7 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -629,10 +629,61 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
629 | ((buf[0] & 0x04) >> 1) | | 629 | ((buf[0] & 0x04) >> 1) | |
630 | ((buf[3] & 0x04) >> 2)); | 630 | ((buf[3] & 0x04) >> 2)); |
631 | 631 | ||
632 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | ||
633 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && | ||
634 | hw->w == 2) { | ||
635 | synaptics_parse_agm(buf, priv, hw); | ||
636 | return 1; | ||
637 | } | ||
638 | |||
639 | hw->x = (((buf[3] & 0x10) << 8) | | ||
640 | ((buf[1] & 0x0f) << 8) | | ||
641 | buf[4]); | ||
642 | hw->y = (((buf[3] & 0x20) << 7) | | ||
643 | ((buf[1] & 0xf0) << 4) | | ||
644 | buf[5]); | ||
645 | hw->z = buf[2]; | ||
646 | |||
632 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 647 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
633 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 648 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
634 | 649 | ||
635 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 650 | if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) { |
651 | /* | ||
652 | * ForcePads, like Clickpads, use middle button | ||
653 | * bits to report primary button clicks. | ||
654 | * Unfortunately they report primary button not | ||
655 | * only when user presses on the pad above certain | ||
656 | * threshold, but also when there are more than one | ||
657 | * finger on the touchpad, which interferes with | ||
658 | * out multi-finger gestures. | ||
659 | */ | ||
660 | if (hw->z == 0) { | ||
661 | /* No contacts */ | ||
662 | priv->press = priv->report_press = false; | ||
663 | } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) { | ||
664 | /* | ||
665 | * Single-finger touch with pressure above | ||
666 | * the threshold. If pressure stays long | ||
667 | * enough, we'll start reporting primary | ||
668 | * button. We rely on the device continuing | ||
669 | * sending data even if finger does not | ||
670 | * move. | ||
671 | */ | ||
672 | if (!priv->press) { | ||
673 | priv->press_start = jiffies; | ||
674 | priv->press = true; | ||
675 | } else if (time_after(jiffies, | ||
676 | priv->press_start + | ||
677 | msecs_to_jiffies(50))) { | ||
678 | priv->report_press = true; | ||
679 | } | ||
680 | } else { | ||
681 | priv->press = false; | ||
682 | } | ||
683 | |||
684 | hw->left = priv->report_press; | ||
685 | |||
686 | } else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | ||
636 | /* | 687 | /* |
637 | * Clickpad's button is transmitted as middle button, | 688 | * Clickpad's button is transmitted as middle button, |
638 | * however, since it is primary button, we will report | 689 | * however, since it is primary button, we will report |
@@ -651,21 +702,6 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
651 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 702 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
652 | } | 703 | } |
653 | 704 | ||
654 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || | ||
655 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && | ||
656 | hw->w == 2) { | ||
657 | synaptics_parse_agm(buf, priv, hw); | ||
658 | return 1; | ||
659 | } | ||
660 | |||
661 | hw->x = (((buf[3] & 0x10) << 8) | | ||
662 | ((buf[1] & 0x0f) << 8) | | ||
663 | buf[4]); | ||
664 | hw->y = (((buf[3] & 0x20) << 7) | | ||
665 | ((buf[1] & 0xf0) << 4) | | ||
666 | buf[5]); | ||
667 | hw->z = buf[2]; | ||
668 | |||
669 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | 705 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && |
670 | ((buf[0] ^ buf[3]) & 0x02)) { | 706 | ((buf[0] ^ buf[3]) & 0x02)) { |
671 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | 707 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index e594af0b264b..fb2e076738ae 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -78,6 +78,11 @@ | |||
78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only | 78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only |
79 | * reports 2. | 79 | * reports 2. |
80 | * 2 0x20 report min query 0x0f gives min coord reported | 80 | * 2 0x20 report min query 0x0f gives min coord reported |
81 | * 2 0x80 forcepad forcepad is a variant of clickpad that | ||
82 | * does not have physical buttons but rather | ||
83 | * uses pressure above certain threshold to | ||
84 | * report primary clicks. Forcepads also have | ||
85 | * clickpad bit set. | ||
81 | */ | 86 | */ |
82 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 87 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
83 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | 88 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ |
@@ -86,6 +91,7 @@ | |||
86 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 91 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
87 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | 92 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
88 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) | 93 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) |
94 | #define SYN_CAP_FORCEPAD(ex0c) ((ex0c) & 0x008000) | ||
89 | 95 | ||
90 | /* synaptics modes query bits */ | 96 | /* synaptics modes query bits */ |
91 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 97 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -177,6 +183,11 @@ struct synaptics_data { | |||
177 | */ | 183 | */ |
178 | struct synaptics_hw_state agm; | 184 | struct synaptics_hw_state agm; |
179 | bool agm_pending; /* new AGM packet received */ | 185 | bool agm_pending; /* new AGM packet received */ |
186 | |||
187 | /* ForcePad handling */ | ||
188 | unsigned long press_start; | ||
189 | bool press; | ||
190 | bool report_press; | ||
180 | }; | 191 | }; |
181 | 192 | ||
182 | void synaptics_module_init(void); | 193 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index e122bda16aab..6bcc0189c1c9 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c | |||
@@ -387,6 +387,7 @@ static int synusb_probe(struct usb_interface *intf, | |||
387 | __set_bit(EV_REL, input_dev->evbit); | 387 | __set_bit(EV_REL, input_dev->evbit); |
388 | __set_bit(REL_X, input_dev->relbit); | 388 | __set_bit(REL_X, input_dev->relbit); |
389 | __set_bit(REL_Y, input_dev->relbit); | 389 | __set_bit(REL_Y, input_dev->relbit); |
390 | __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit); | ||
390 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); | 391 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); |
391 | } else { | 392 | } else { |
392 | input_set_abs_params(input_dev, ABS_X, | 393 | input_set_abs_params(input_dev, ABS_X, |
@@ -401,6 +402,11 @@ static int synusb_probe(struct usb_interface *intf, | |||
401 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 402 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
402 | } | 403 | } |
403 | 404 | ||
405 | if (synusb->flags & SYNUSB_TOUCHSCREEN) | ||
406 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
407 | else | ||
408 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
409 | |||
404 | __set_bit(BTN_LEFT, input_dev->keybit); | 410 | __set_bit(BTN_LEFT, input_dev->keybit); |
405 | __set_bit(BTN_RIGHT, input_dev->keybit); | 411 | __set_bit(BTN_RIGHT, input_dev->keybit); |
406 | __set_bit(BTN_MIDDLE, input_dev->keybit); | 412 | __set_bit(BTN_MIDDLE, input_dev->keybit); |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index ca843b6cf6bd..30c8b6998808 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -393,6 +393,9 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
393 | if ((button_info & 0x0f) >= 3) | 393 | if ((button_info & 0x0f) >= 3) |
394 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 394 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
395 | 395 | ||
396 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); | ||
397 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); | ||
398 | |||
396 | trackpoint_defaults(psmouse->private); | 399 | trackpoint_defaults(psmouse->private); |
397 | 400 | ||
398 | error = trackpoint_power_on_reset(&psmouse->ps2dev); | 401 | error = trackpoint_power_on_reset(&psmouse->ps2dev); |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 0cb7ef59071b..69175b825346 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/serio.h> | 22 | #include <linux/serio.h> |
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/compat.h> | ||
24 | 25 | ||
25 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | 26 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); |
26 | MODULE_DESCRIPTION("Input device TTY line discipline"); | 27 | MODULE_DESCRIPTION("Input device TTY line discipline"); |
@@ -198,28 +199,55 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
198 | return 0; | 199 | return 0; |
199 | } | 200 | } |
200 | 201 | ||
202 | static void serport_set_type(struct tty_struct *tty, unsigned long type) | ||
203 | { | ||
204 | struct serport *serport = tty->disc_data; | ||
205 | |||
206 | serport->id.proto = type & 0x000000ff; | ||
207 | serport->id.id = (type & 0x0000ff00) >> 8; | ||
208 | serport->id.extra = (type & 0x00ff0000) >> 16; | ||
209 | } | ||
210 | |||
201 | /* | 211 | /* |
202 | * serport_ldisc_ioctl() allows to set the port protocol, and device ID | 212 | * serport_ldisc_ioctl() allows to set the port protocol, and device ID |
203 | */ | 213 | */ |
204 | 214 | ||
205 | static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) | 215 | static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file, |
216 | unsigned int cmd, unsigned long arg) | ||
206 | { | 217 | { |
207 | struct serport *serport = (struct serport*) tty->disc_data; | ||
208 | unsigned long type; | ||
209 | |||
210 | if (cmd == SPIOCSTYPE) { | 218 | if (cmd == SPIOCSTYPE) { |
219 | unsigned long type; | ||
220 | |||
211 | if (get_user(type, (unsigned long __user *) arg)) | 221 | if (get_user(type, (unsigned long __user *) arg)) |
212 | return -EFAULT; | 222 | return -EFAULT; |
213 | 223 | ||
214 | serport->id.proto = type & 0x000000ff; | 224 | serport_set_type(tty, type); |
215 | serport->id.id = (type & 0x0000ff00) >> 8; | 225 | return 0; |
216 | serport->id.extra = (type & 0x00ff0000) >> 16; | 226 | } |
227 | |||
228 | return -EINVAL; | ||
229 | } | ||
230 | |||
231 | #ifdef CONFIG_COMPAT | ||
232 | #define COMPAT_SPIOCSTYPE _IOW('q', 0x01, compat_ulong_t) | ||
233 | static long serport_ldisc_compat_ioctl(struct tty_struct *tty, | ||
234 | struct file *file, | ||
235 | unsigned int cmd, unsigned long arg) | ||
236 | { | ||
237 | if (cmd == COMPAT_SPIOCSTYPE) { | ||
238 | void __user *uarg = compat_ptr(arg); | ||
239 | compat_ulong_t compat_type; | ||
240 | |||
241 | if (get_user(compat_type, (compat_ulong_t __user *)uarg)) | ||
242 | return -EFAULT; | ||
217 | 243 | ||
244 | serport_set_type(tty, compat_type); | ||
218 | return 0; | 245 | return 0; |
219 | } | 246 | } |
220 | 247 | ||
221 | return -EINVAL; | 248 | return -EINVAL; |
222 | } | 249 | } |
250 | #endif | ||
223 | 251 | ||
224 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) | 252 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) |
225 | { | 253 | { |
@@ -243,6 +271,9 @@ static struct tty_ldisc_ops serport_ldisc = { | |||
243 | .close = serport_ldisc_close, | 271 | .close = serport_ldisc_close, |
244 | .read = serport_ldisc_read, | 272 | .read = serport_ldisc_read, |
245 | .ioctl = serport_ldisc_ioctl, | 273 | .ioctl = serport_ldisc_ioctl, |
274 | #ifdef CONFIG_COMPAT | ||
275 | .compat_ioctl = serport_ldisc_compat_ioctl, | ||
276 | #endif | ||
246 | .receive_buf = serport_ldisc_receive, | 277 | .receive_buf = serport_ldisc_receive, |
247 | .write_wakeup = serport_ldisc_write_wakeup | 278 | .write_wakeup = serport_ldisc_write_wakeup |
248 | }; | 279 | }; |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index db178ed2b47e..aaacf8bfa61f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -837,7 +837,12 @@ static irqreturn_t mxt_process_messages_t44(struct mxt_data *data) | |||
837 | count = data->msg_buf[0]; | 837 | count = data->msg_buf[0]; |
838 | 838 | ||
839 | if (count == 0) { | 839 | if (count == 0) { |
840 | dev_warn(dev, "Interrupt triggered but zero messages\n"); | 840 | /* |
841 | * This condition is caused by the CHG line being configured | ||
842 | * in Mode 0. It results in unnecessary I2C operations but it | ||
843 | * is benign. | ||
844 | */ | ||
845 | dev_dbg(dev, "Interrupt triggered but zero messages\n"); | ||
841 | return IRQ_NONE; | 846 | return IRQ_NONE; |
842 | } else if (count > data->max_reportid) { | 847 | } else if (count > data->max_reportid) { |
843 | dev_err(dev, "T44 count %d exceeded max report id\n", count); | 848 | dev_err(dev, "T44 count %d exceeded max report id\n", count); |
@@ -1374,11 +1379,16 @@ static int mxt_get_info(struct mxt_data *data) | |||
1374 | return 0; | 1379 | return 0; |
1375 | } | 1380 | } |
1376 | 1381 | ||
1377 | static void mxt_free_object_table(struct mxt_data *data) | 1382 | static void mxt_free_input_device(struct mxt_data *data) |
1378 | { | 1383 | { |
1379 | input_unregister_device(data->input_dev); | 1384 | if (data->input_dev) { |
1380 | data->input_dev = NULL; | 1385 | input_unregister_device(data->input_dev); |
1386 | data->input_dev = NULL; | ||
1387 | } | ||
1388 | } | ||
1381 | 1389 | ||
1390 | static void mxt_free_object_table(struct mxt_data *data) | ||
1391 | { | ||
1382 | kfree(data->object_table); | 1392 | kfree(data->object_table); |
1383 | data->object_table = NULL; | 1393 | data->object_table = NULL; |
1384 | kfree(data->msg_buf); | 1394 | kfree(data->msg_buf); |
@@ -1957,11 +1967,13 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
1957 | ret = mxt_lookup_bootloader_address(data, 0); | 1967 | ret = mxt_lookup_bootloader_address(data, 0); |
1958 | if (ret) | 1968 | if (ret) |
1959 | goto release_firmware; | 1969 | goto release_firmware; |
1970 | |||
1971 | mxt_free_input_device(data); | ||
1972 | mxt_free_object_table(data); | ||
1960 | } else { | 1973 | } else { |
1961 | enable_irq(data->irq); | 1974 | enable_irq(data->irq); |
1962 | } | 1975 | } |
1963 | 1976 | ||
1964 | mxt_free_object_table(data); | ||
1965 | reinit_completion(&data->bl_completion); | 1977 | reinit_completion(&data->bl_completion); |
1966 | 1978 | ||
1967 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); | 1979 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); |
@@ -2210,6 +2222,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
2210 | return 0; | 2222 | return 0; |
2211 | 2223 | ||
2212 | err_free_object: | 2224 | err_free_object: |
2225 | mxt_free_input_device(data); | ||
2213 | mxt_free_object_table(data); | 2226 | mxt_free_object_table(data); |
2214 | err_free_irq: | 2227 | err_free_irq: |
2215 | free_irq(client->irq, data); | 2228 | free_irq(client->irq, data); |
@@ -2224,7 +2237,7 @@ static int mxt_remove(struct i2c_client *client) | |||
2224 | 2237 | ||
2225 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); | 2238 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); |
2226 | free_irq(data->irq, data); | 2239 | free_irq(data->irq, data); |
2227 | input_unregister_device(data->input_dev); | 2240 | mxt_free_input_device(data); |
2228 | mxt_free_object_table(data); | 2241 | mxt_free_object_table(data); |
2229 | kfree(data); | 2242 | kfree(data); |
2230 | 2243 | ||
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c index 16b52115c27f..705ffa1e064a 100644 --- a/drivers/input/touchscreen/wm9712.c +++ b/drivers/input/touchscreen/wm9712.c | |||
@@ -41,7 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | static int rpu = 8; | 42 | static int rpu = 8; |
43 | module_param(rpu, int, 0); | 43 | module_param(rpu, int, 0); |
44 | MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); | 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect."); |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Set current used for pressure measurement. | 47 | * Set current used for pressure measurement. |
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c index 7405353199d7..572a5a64face 100644 --- a/drivers/input/touchscreen/wm9713.c +++ b/drivers/input/touchscreen/wm9713.c | |||
@@ -41,7 +41,7 @@ | |||
41 | */ | 41 | */ |
42 | static int rpu = 8; | 42 | static int rpu = 8; |
43 | module_param(rpu, int, 0); | 43 | module_param(rpu, int, 0); |
44 | MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect."); | 44 | MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect."); |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Set current used for pressure measurement. | 47 | * Set current used for pressure measurement. |
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index 19df18c9b8be..1874ebe9ac1e 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h | |||
@@ -165,6 +165,7 @@ struct input_keymap_entry { | |||
165 | #define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */ | 165 | #define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */ |
166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ | 166 | #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ |
167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ | 167 | #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ |
168 | #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ | ||
168 | 169 | ||
169 | #define INPUT_PROP_MAX 0x1f | 170 | #define INPUT_PROP_MAX 0x1f |
170 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) | 171 | #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) |