diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index ad6217467676..32d70ed8f41d 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/serio.h> | 20 | #include <linux/serio.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/libps2.h> | 22 | #include <linux/libps2.h> |
23 | #include <linux/mutex.h> | ||
24 | |||
23 | #include "psmouse.h" | 25 | #include "psmouse.h" |
24 | #include "synaptics.h" | 26 | #include "synaptics.h" |
25 | #include "logips2pp.h" | 27 | #include "logips2pp.h" |
@@ -98,13 +100,13 @@ __obsolete_setup("psmouse_resetafter="); | |||
98 | __obsolete_setup("psmouse_rate="); | 100 | __obsolete_setup("psmouse_rate="); |
99 | 101 | ||
100 | /* | 102 | /* |
101 | * psmouse_sem protects all operations changing state of mouse | 103 | * psmouse_mutex protects all operations changing state of mouse |
102 | * (connecting, disconnecting, changing rate or resolution via | 104 | * (connecting, disconnecting, changing rate or resolution via |
103 | * sysfs). We could use a per-device semaphore but since there | 105 | * sysfs). We could use a per-device semaphore but since there |
104 | * rarely more than one PS/2 mouse connected and since semaphore | 106 | * rarely more than one PS/2 mouse connected and since semaphore |
105 | * is taken in "slow" paths it is not worth it. | 107 | * is taken in "slow" paths it is not worth it. |
106 | */ | 108 | */ |
107 | static DECLARE_MUTEX(psmouse_sem); | 109 | static DEFINE_MUTEX(psmouse_mutex); |
108 | 110 | ||
109 | static struct workqueue_struct *kpsmoused_wq; | 111 | static struct workqueue_struct *kpsmoused_wq; |
110 | 112 | ||
@@ -868,7 +870,7 @@ static void psmouse_resync(void *p) | |||
868 | int failed = 0, enabled = 0; | 870 | int failed = 0, enabled = 0; |
869 | int i; | 871 | int i; |
870 | 872 | ||
871 | down(&psmouse_sem); | 873 | mutex_lock(&psmouse_mutex); |
872 | 874 | ||
873 | if (psmouse->state != PSMOUSE_RESYNCING) | 875 | if (psmouse->state != PSMOUSE_RESYNCING) |
874 | goto out; | 876 | goto out; |
@@ -948,7 +950,7 @@ static void psmouse_resync(void *p) | |||
948 | if (parent) | 950 | if (parent) |
949 | psmouse_activate(parent); | 951 | psmouse_activate(parent); |
950 | out: | 952 | out: |
951 | up(&psmouse_sem); | 953 | mutex_unlock(&psmouse_mutex); |
952 | } | 954 | } |
953 | 955 | ||
954 | /* | 956 | /* |
@@ -974,14 +976,14 @@ static void psmouse_disconnect(struct serio *serio) | |||
974 | 976 | ||
975 | sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); | 977 | sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group); |
976 | 978 | ||
977 | down(&psmouse_sem); | 979 | mutex_lock(&psmouse_mutex); |
978 | 980 | ||
979 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 981 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
980 | 982 | ||
981 | /* make sure we don't have a resync in progress */ | 983 | /* make sure we don't have a resync in progress */ |
982 | up(&psmouse_sem); | 984 | mutex_unlock(&psmouse_mutex); |
983 | flush_workqueue(kpsmoused_wq); | 985 | flush_workqueue(kpsmoused_wq); |
984 | down(&psmouse_sem); | 986 | mutex_lock(&psmouse_mutex); |
985 | 987 | ||
986 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 988 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
987 | parent = serio_get_drvdata(serio->parent); | 989 | parent = serio_get_drvdata(serio->parent); |
@@ -1004,7 +1006,7 @@ static void psmouse_disconnect(struct serio *serio) | |||
1004 | if (parent) | 1006 | if (parent) |
1005 | psmouse_activate(parent); | 1007 | psmouse_activate(parent); |
1006 | 1008 | ||
1007 | up(&psmouse_sem); | 1009 | mutex_unlock(&psmouse_mutex); |
1008 | } | 1010 | } |
1009 | 1011 | ||
1010 | static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) | 1012 | static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) |
@@ -1076,7 +1078,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1076 | struct input_dev *input_dev; | 1078 | struct input_dev *input_dev; |
1077 | int retval = -ENOMEM; | 1079 | int retval = -ENOMEM; |
1078 | 1080 | ||
1079 | down(&psmouse_sem); | 1081 | mutex_lock(&psmouse_mutex); |
1080 | 1082 | ||
1081 | /* | 1083 | /* |
1082 | * If this is a pass-through port deactivate parent so the device | 1084 | * If this is a pass-through port deactivate parent so the device |
@@ -1144,7 +1146,7 @@ out: | |||
1144 | if (parent) | 1146 | if (parent) |
1145 | psmouse_activate(parent); | 1147 | psmouse_activate(parent); |
1146 | 1148 | ||
1147 | up(&psmouse_sem); | 1149 | mutex_unlock(&psmouse_mutex); |
1148 | return retval; | 1150 | return retval; |
1149 | } | 1151 | } |
1150 | 1152 | ||
@@ -1161,7 +1163,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1161 | return -1; | 1163 | return -1; |
1162 | } | 1164 | } |
1163 | 1165 | ||
1164 | down(&psmouse_sem); | 1166 | mutex_lock(&psmouse_mutex); |
1165 | 1167 | ||
1166 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 1168 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
1167 | parent = serio_get_drvdata(serio->parent); | 1169 | parent = serio_get_drvdata(serio->parent); |
@@ -1195,7 +1197,7 @@ out: | |||
1195 | if (parent) | 1197 | if (parent) |
1196 | psmouse_activate(parent); | 1198 | psmouse_activate(parent); |
1197 | 1199 | ||
1198 | up(&psmouse_sem); | 1200 | mutex_unlock(&psmouse_mutex); |
1199 | return rc; | 1201 | return rc; |
1200 | } | 1202 | } |
1201 | 1203 | ||
@@ -1273,7 +1275,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1273 | goto out_unpin; | 1275 | goto out_unpin; |
1274 | } | 1276 | } |
1275 | 1277 | ||
1276 | retval = down_interruptible(&psmouse_sem); | 1278 | retval = mutex_lock_interruptible(&psmouse_mutex); |
1277 | if (retval) | 1279 | if (retval) |
1278 | goto out_unpin; | 1280 | goto out_unpin; |
1279 | 1281 | ||
@@ -1281,7 +1283,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1281 | 1283 | ||
1282 | if (psmouse->state == PSMOUSE_IGNORE) { | 1284 | if (psmouse->state == PSMOUSE_IGNORE) { |
1283 | retval = -ENODEV; | 1285 | retval = -ENODEV; |
1284 | goto out_up; | 1286 | goto out_unlock; |
1285 | } | 1287 | } |
1286 | 1288 | ||
1287 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 1289 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
@@ -1299,8 +1301,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev | |||
1299 | if (parent) | 1301 | if (parent) |
1300 | psmouse_activate(parent); | 1302 | psmouse_activate(parent); |
1301 | 1303 | ||
1302 | out_up: | 1304 | out_unlock: |
1303 | up(&psmouse_sem); | 1305 | mutex_unlock(&psmouse_mutex); |
1304 | out_unpin: | 1306 | out_unpin: |
1305 | serio_unpin_driver(serio); | 1307 | serio_unpin_driver(serio); |
1306 | return retval; | 1308 | return retval; |
@@ -1357,11 +1359,11 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1357 | return -EIO; | 1359 | return -EIO; |
1358 | } | 1360 | } |
1359 | 1361 | ||
1360 | up(&psmouse_sem); | 1362 | mutex_unlock(&psmouse_mutex); |
1361 | serio_unpin_driver(serio); | 1363 | serio_unpin_driver(serio); |
1362 | serio_unregister_child_port(serio); | 1364 | serio_unregister_child_port(serio); |
1363 | serio_pin_driver_uninterruptible(serio); | 1365 | serio_pin_driver_uninterruptible(serio); |
1364 | down(&psmouse_sem); | 1366 | mutex_lock(&psmouse_mutex); |
1365 | 1367 | ||
1366 | if (serio->drv != &psmouse_drv) { | 1368 | if (serio->drv != &psmouse_drv) { |
1367 | input_free_device(new_dev); | 1369 | input_free_device(new_dev); |