diff options
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index d8c0c8d6992c..a3c97315a473 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq; | |||
110 | struct psmouse_protocol { | 110 | struct psmouse_protocol { |
111 | enum psmouse_type type; | 111 | enum psmouse_type type; |
112 | bool maxproto; | 112 | bool maxproto; |
113 | bool ignore_parity; /* Protocol should ignore parity errors from KBC */ | ||
113 | const char *name; | 114 | const char *name; |
114 | const char *alias; | 115 | const char *alias; |
115 | int (*detect)(struct psmouse *, bool); | 116 | int (*detect)(struct psmouse *, bool); |
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
288 | if (psmouse->state == PSMOUSE_IGNORE) | 289 | if (psmouse->state == PSMOUSE_IGNORE) |
289 | goto out; | 290 | goto out; |
290 | 291 | ||
291 | if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) { | 292 | if (unlikely((flags & SERIO_TIMEOUT) || |
293 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | ||
294 | |||
292 | if (psmouse->state == PSMOUSE_ACTIVATED) | 295 | if (psmouse->state == PSMOUSE_ACTIVATED) |
293 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", | 296 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", |
294 | flags & SERIO_TIMEOUT ? " timeout" : "", | 297 | flags & SERIO_TIMEOUT ? " timeout" : "", |
@@ -759,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
759 | .name = "PS/2", | 762 | .name = "PS/2", |
760 | .alias = "bare", | 763 | .alias = "bare", |
761 | .maxproto = true, | 764 | .maxproto = true, |
765 | .ignore_parity = true, | ||
762 | .detect = ps2bare_detect, | 766 | .detect = ps2bare_detect, |
763 | }, | 767 | }, |
764 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | 768 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP |
@@ -786,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
786 | .name = "ImPS/2", | 790 | .name = "ImPS/2", |
787 | .alias = "imps", | 791 | .alias = "imps", |
788 | .maxproto = true, | 792 | .maxproto = true, |
793 | .ignore_parity = true, | ||
789 | .detect = intellimouse_detect, | 794 | .detect = intellimouse_detect, |
790 | }, | 795 | }, |
791 | { | 796 | { |
@@ -793,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
793 | .name = "ImExPS/2", | 798 | .name = "ImExPS/2", |
794 | .alias = "exps", | 799 | .alias = "exps", |
795 | .maxproto = true, | 800 | .maxproto = true, |
801 | .ignore_parity = true, | ||
796 | .detect = im_explorer_detect, | 802 | .detect = im_explorer_detect, |
797 | }, | 803 | }, |
798 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 804 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
@@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct serio *serio) | |||
1222 | static int psmouse_switch_protocol(struct psmouse *psmouse, | 1228 | static int psmouse_switch_protocol(struct psmouse *psmouse, |
1223 | const struct psmouse_protocol *proto) | 1229 | const struct psmouse_protocol *proto) |
1224 | { | 1230 | { |
1231 | const struct psmouse_protocol *selected_proto; | ||
1225 | struct input_dev *input_dev = psmouse->dev; | 1232 | struct input_dev *input_dev = psmouse->dev; |
1226 | 1233 | ||
1227 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; | 1234 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
@@ -1245,9 +1252,14 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1245 | return -1; | 1252 | return -1; |
1246 | 1253 | ||
1247 | psmouse->type = proto->type; | 1254 | psmouse->type = proto->type; |
1248 | } else | 1255 | selected_proto = proto; |
1256 | } else { | ||
1249 | psmouse->type = psmouse_extensions(psmouse, | 1257 | psmouse->type = psmouse_extensions(psmouse, |
1250 | psmouse_max_proto, true); | 1258 | psmouse_max_proto, true); |
1259 | selected_proto = psmouse_protocol_by_type(psmouse->type); | ||
1260 | } | ||
1261 | |||
1262 | psmouse->ignore_parity = selected_proto->ignore_parity; | ||
1251 | 1263 | ||
1252 | /* | 1264 | /* |
1253 | * If mouse's packet size is 3 there is no point in polling the | 1265 | * If mouse's packet size is 3 there is no point in polling the |
@@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, | |||
1267 | psmouse->resync_time = 0; | 1279 | psmouse->resync_time = 0; |
1268 | 1280 | ||
1269 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", | 1281 | snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s", |
1270 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | 1282 | selected_proto->name, psmouse->vendor, psmouse->name); |
1271 | 1283 | ||
1272 | input_dev->name = psmouse->devname; | 1284 | input_dev->name = psmouse->devname; |
1273 | input_dev->phys = psmouse->phys; | 1285 | input_dev->phys = psmouse->phys; |
@@ -1382,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
1382 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); |
1383 | struct psmouse *parent = NULL; | 1395 | struct psmouse *parent = NULL; |
1384 | struct serio_driver *drv = serio->drv; | 1396 | struct serio_driver *drv = serio->drv; |
1397 | unsigned char type; | ||
1385 | int rc = -1; | 1398 | int rc = -1; |
1386 | 1399 | ||
1387 | if (!drv || !psmouse) { | 1400 | if (!drv || !psmouse) { |
@@ -1401,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
1401 | if (psmouse->reconnect) { | 1414 | if (psmouse->reconnect) { |
1402 | if (psmouse->reconnect(psmouse)) | 1415 | if (psmouse->reconnect(psmouse)) |
1403 | goto out; | 1416 | goto out; |
1404 | } else if (psmouse_probe(psmouse) < 0 || | 1417 | } else { |
1405 | psmouse->type != psmouse_extensions(psmouse, | 1418 | psmouse_reset(psmouse); |
1406 | psmouse_max_proto, false)) { | 1419 | |
1407 | goto out; | 1420 | if (psmouse_probe(psmouse) < 0) |
1421 | goto out; | ||
1422 | |||
1423 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
1424 | if (psmouse->type != type) | ||
1425 | goto out; | ||
1408 | } | 1426 | } |
1409 | 1427 | ||
1410 | /* ok, the device type (and capabilities) match the old one, | 1428 | /* ok, the device type (and capabilities) match the old one, |