diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r-- | drivers/input/serio/i8042.c | 39 |
1 files changed, 14 insertions, 25 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 7e3141f37e32..debe9445488c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -255,25 +255,10 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) | |||
255 | static int i8042_aux_write(struct serio *serio, unsigned char c) | 255 | static int i8042_aux_write(struct serio *serio, unsigned char c) |
256 | { | 256 | { |
257 | struct i8042_port *port = serio->port_data; | 257 | struct i8042_port *port = serio->port_data; |
258 | int retval; | ||
259 | |||
260 | /* | ||
261 | * Send the byte out. | ||
262 | */ | ||
263 | |||
264 | if (port->mux == -1) | ||
265 | retval = i8042_command(&c, I8042_CMD_AUX_SEND); | ||
266 | else | ||
267 | retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux); | ||
268 | |||
269 | /* | ||
270 | * Make sure the interrupt happens and the character is received even | ||
271 | * in the case the IRQ isn't wired, so that we can receive further | ||
272 | * characters later. | ||
273 | */ | ||
274 | 258 | ||
275 | i8042_interrupt(0, NULL); | 259 | return i8042_command(&c, port->mux == -1 ? |
276 | return retval; | 260 | I8042_CMD_AUX_SEND : |
261 | I8042_CMD_MUX_SEND + port->mux); | ||
277 | } | 262 | } |
278 | 263 | ||
279 | /* | 264 | /* |
@@ -337,23 +322,27 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
337 | dfl = 0; | 322 | dfl = 0; |
338 | if (str & I8042_STR_MUXERR) { | 323 | if (str & I8042_STR_MUXERR) { |
339 | dbg("MUX error, status is %02x, data is %02x", str, data); | 324 | dbg("MUX error, status is %02x, data is %02x", str, data); |
340 | switch (data) { | ||
341 | default: | ||
342 | /* | 325 | /* |
343 | * When MUXERR condition is signalled the data register can only contain | 326 | * When MUXERR condition is signalled the data register can only contain |
344 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | 327 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately |
345 | * it is not always the case. Some KBC just get confused which port the | 328 | * it is not always the case. Some KBCs also report 0xfc when there is |
346 | * data came from and signal error leaving the data intact. They _do not_ | 329 | * nothing connected to the port while others sometimes get confused which |
347 | * revert to legacy mode (actually I've never seen KBC reverting to legacy | 330 | * port the data came from and signal error leaving the data intact. They |
348 | * mode yet, when we see one we'll add proper handling). | 331 | * _do not_ revert to legacy mode (actually I've never seen KBC reverting |
349 | * Anyway, we will assume that the data came from the same serio last byte | 332 | * to legacy mode yet, when we see one we'll add proper handling). |
333 | * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the | ||
334 | * rest assume that the data came from the same serio last byte | ||
350 | * was transmitted (if transmission happened not too long ago). | 335 | * was transmitted (if transmission happened not too long ago). |
351 | */ | 336 | */ |
337 | |||
338 | switch (data) { | ||
339 | default: | ||
352 | if (time_before(jiffies, last_transmit + HZ/10)) { | 340 | if (time_before(jiffies, last_transmit + HZ/10)) { |
353 | str = last_str; | 341 | str = last_str; |
354 | break; | 342 | break; |
355 | } | 343 | } |
356 | /* fall through - report timeout */ | 344 | /* fall through - report timeout */ |
345 | case 0xfc: | ||
357 | case 0xfd: | 346 | case 0xfd: |
358 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; | 347 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; |
359 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; | 348 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; |