aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov2006-11-17 01:07:06 -0500
committerDmitry Torokhov2006-11-17 01:07:06 -0500
commita216a4b6e6f1fdfd3d1f20f03d9d45f05a63d643 (patch)
tree6c593ead32aadd41014fec7a54357ff90b51de77 /drivers
parent6c595fb12fa6c1fe382cc086fdade4acd93c643f (diff)
Input: i8042 - fix shutdown issue on some boxes with active MUXes
MUX error handling has a workaround for KBCs that get confused which port data came from and signal MUXERR while data is actually good. Unfortunately this workaround hurts with KBCs that signal timeouts as 0xfc (spec says that only 0xfd, 0xfe and 0xff are alowed with MUXERR) since it causes endless attempts to rescan i8042 serio ports. The solution is to treat 0xfc as timeout (0xfe). Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/serio/i8042.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index d365f227ac56..debe9445488c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -322,23 +322,27 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
dfl = 0;
if (str & I8042_STR_MUXERR) {
dbg("MUX error, status is %02x, data is %02x", str, data);
- switch (data) {
- default:
/*
* When MUXERR condition is signalled the data register can only contain
* 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
- * it is not always the case. Some KBC just get confused which port the
- * data came from and signal error leaving the data intact. They _do not_
- * revert to legacy mode (actually I've never seen KBC reverting to legacy
- * mode yet, when we see one we'll add proper handling).
- * Anyway, we will assume that the data came from the same serio last byte
+ * it is not always the case. Some KBCs also report 0xfc when there is
+ * nothing connected to the port while others sometimes get confused which
+ * port the data came from and signal error leaving the data intact. They
+ * _do not_ revert to legacy mode (actually I've never seen KBC reverting
+ * to legacy mode yet, when we see one we'll add proper handling).
+ * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
+ * rest assume that the data came from the same serio last byte
* was transmitted (if transmission happened not too long ago).
*/
+
+ switch (data) {
+ default:
if (time_before(jiffies, last_transmit + HZ/10)) {
str = last_str;
break;
}
/* fall through - report timeout */
+ case 0xfc:
case 0xfd:
case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break;
case 0xff: dfl = SERIO_PARITY; data = 0xfe; break;