diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 78 |
1 files changed, 34 insertions, 44 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 401ac6b6edd4..d8c0c8d6992c 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -627,8 +627,15 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 627 | synaptics_hardware = true; | 627 | synaptics_hardware = true; |
| 628 | 628 | ||
| 629 | if (max_proto > PSMOUSE_IMEX) { | 629 | if (max_proto > PSMOUSE_IMEX) { |
| 630 | if (!set_properties || synaptics_init(psmouse) == 0) | 630 | /* |
| 631 | * Try activating protocol, but check if support is enabled first, since | ||
| 632 | * we try detecting Synaptics even when protocol is disabled. | ||
| 633 | */ | ||
| 634 | if (synaptics_supported() && | ||
| 635 | (!set_properties || synaptics_init(psmouse) == 0)) { | ||
| 631 | return PSMOUSE_SYNAPTICS; | 636 | return PSMOUSE_SYNAPTICS; |
| 637 | } | ||
| 638 | |||
| 632 | /* | 639 | /* |
| 633 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). | 640 | * Some Synaptics touchpads can emulate extended protocols (like IMPS/2). |
| 634 | * Unfortunately Logitech/Genius probes confuse some firmware versions so | 641 | * Unfortunately Logitech/Genius probes confuse some firmware versions so |
| @@ -683,19 +690,6 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 683 | max_proto = PSMOUSE_IMEX; | 690 | max_proto = PSMOUSE_IMEX; |
| 684 | } | 691 | } |
| 685 | 692 | ||
| 686 | /* | ||
| 687 | * Try Finger Sensing Pad | ||
| 688 | */ | ||
| 689 | if (max_proto > PSMOUSE_IMEX) { | ||
| 690 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
| 691 | if (!set_properties || fsp_init(psmouse) == 0) | ||
| 692 | return PSMOUSE_FSP; | ||
| 693 | /* | ||
| 694 | * Init failed, try basic relative protocols | ||
| 695 | */ | ||
| 696 | max_proto = PSMOUSE_IMEX; | ||
| 697 | } | ||
| 698 | } | ||
| 699 | 693 | ||
| 700 | if (max_proto > PSMOUSE_IMEX) { | 694 | if (max_proto > PSMOUSE_IMEX) { |
| 701 | if (genius_detect(psmouse, set_properties) == 0) | 695 | if (genius_detect(psmouse, set_properties) == 0) |
| @@ -712,6 +706,21 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 712 | } | 706 | } |
| 713 | 707 | ||
| 714 | /* | 708 | /* |
| 709 | * Try Finger Sensing Pad. We do it here because its probe upsets | ||
| 710 | * Trackpoint devices (causing TP_READ_ID command to time out). | ||
| 711 | */ | ||
| 712 | if (max_proto > PSMOUSE_IMEX) { | ||
| 713 | if (fsp_detect(psmouse, set_properties) == 0) { | ||
| 714 | if (!set_properties || fsp_init(psmouse) == 0) | ||
| 715 | return PSMOUSE_FSP; | ||
| 716 | /* | ||
| 717 | * Init failed, try basic relative protocols | ||
| 718 | */ | ||
| 719 | max_proto = PSMOUSE_IMEX; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | /* | ||
| 715 | * Reset to defaults in case the device got confused by extended | 724 | * Reset to defaults in case the device got confused by extended |
| 716 | * protocol probes. Note that we follow up with full reset because | 725 | * protocol probes. Note that we follow up with full reset because |
| 717 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. | 726 | * some mice put themselves to sleep when they see PSMOUSE_RESET_DIS. |
| @@ -1132,7 +1141,14 @@ static void psmouse_cleanup(struct serio *serio) | |||
| 1132 | psmouse_deactivate(parent); | 1141 | psmouse_deactivate(parent); |
| 1133 | } | 1142 | } |
| 1134 | 1143 | ||
| 1135 | psmouse_deactivate(psmouse); | 1144 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
| 1145 | |||
| 1146 | /* | ||
| 1147 | * Disable stream mode so cleanup routine can proceed undisturbed. | ||
| 1148 | */ | ||
| 1149 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | ||
| 1150 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", | ||
| 1151 | psmouse->ps2dev.serio->phys); | ||
| 1136 | 1152 | ||
| 1137 | if (psmouse->cleanup) | 1153 | if (psmouse->cleanup) |
| 1138 | psmouse->cleanup(psmouse); | 1154 | psmouse->cleanup(psmouse); |
| @@ -1450,24 +1466,10 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *de | |||
| 1450 | struct serio *serio = to_serio_port(dev); | 1466 | struct serio *serio = to_serio_port(dev); |
| 1451 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); | 1467 | struct psmouse_attribute *attr = to_psmouse_attr(devattr); |
| 1452 | struct psmouse *psmouse; | 1468 | struct psmouse *psmouse; |
| 1453 | int retval; | ||
| 1454 | |||
| 1455 | retval = serio_pin_driver(serio); | ||
| 1456 | if (retval) | ||
| 1457 | return retval; | ||
| 1458 | |||
| 1459 | if (serio->drv != &psmouse_drv) { | ||
| 1460 | retval = -ENODEV; | ||
| 1461 | goto out; | ||
| 1462 | } | ||
| 1463 | 1469 | ||
| 1464 | psmouse = serio_get_drvdata(serio); | 1470 | psmouse = serio_get_drvdata(serio); |
| 1465 | 1471 | ||
| 1466 | retval = attr->show(psmouse, attr->data, buf); | 1472 | return attr->show(psmouse, attr->data, buf); |
| 1467 | |||
| 1468 | out: | ||
| 1469 | serio_unpin_driver(serio); | ||
| 1470 | return retval; | ||
| 1471 | } | 1473 | } |
| 1472 | 1474 | ||
| 1473 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, | 1475 | ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr, |
| @@ -1478,18 +1480,9 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
| 1478 | struct psmouse *psmouse, *parent = NULL; | 1480 | struct psmouse *psmouse, *parent = NULL; |
| 1479 | int retval; | 1481 | int retval; |
| 1480 | 1482 | ||
| 1481 | retval = serio_pin_driver(serio); | ||
| 1482 | if (retval) | ||
| 1483 | return retval; | ||
| 1484 | |||
| 1485 | if (serio->drv != &psmouse_drv) { | ||
| 1486 | retval = -ENODEV; | ||
| 1487 | goto out_unpin; | ||
| 1488 | } | ||
| 1489 | |||
| 1490 | retval = mutex_lock_interruptible(&psmouse_mutex); | 1483 | retval = mutex_lock_interruptible(&psmouse_mutex); |
| 1491 | if (retval) | 1484 | if (retval) |
| 1492 | goto out_unpin; | 1485 | goto out; |
| 1493 | 1486 | ||
| 1494 | psmouse = serio_get_drvdata(serio); | 1487 | psmouse = serio_get_drvdata(serio); |
| 1495 | 1488 | ||
| @@ -1519,8 +1512,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
| 1519 | 1512 | ||
| 1520 | out_unlock: | 1513 | out_unlock: |
| 1521 | mutex_unlock(&psmouse_mutex); | 1514 | mutex_unlock(&psmouse_mutex); |
| 1522 | out_unpin: | 1515 | out: |
| 1523 | serio_unpin_driver(serio); | ||
| 1524 | return retval; | 1516 | return retval; |
| 1525 | } | 1517 | } |
| 1526 | 1518 | ||
| @@ -1582,9 +1574,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
| 1582 | } | 1574 | } |
| 1583 | 1575 | ||
| 1584 | mutex_unlock(&psmouse_mutex); | 1576 | mutex_unlock(&psmouse_mutex); |
| 1585 | serio_unpin_driver(serio); | ||
| 1586 | serio_unregister_child_port(serio); | 1577 | serio_unregister_child_port(serio); |
| 1587 | serio_pin_driver_uninterruptible(serio); | ||
| 1588 | mutex_lock(&psmouse_mutex); | 1578 | mutex_lock(&psmouse_mutex); |
| 1589 | 1579 | ||
| 1590 | if (serio->drv != &psmouse_drv) { | 1580 | if (serio->drv != &psmouse_drv) { |
