aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/i8042.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index b53a015bf8a5..8aaf8fcacf62 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -264,6 +264,49 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
264 I8042_CMD_MUX_SEND + port->mux); 264 I8042_CMD_MUX_SEND + port->mux);
265} 265}
266 266
267
268/*
269 * i8042_aux_close attempts to clear AUX or KBD port state by disabling
270 * and then re-enabling it.
271 */
272
273static void i8042_port_close(struct serio *serio)
274{
275 int irq_bit;
276 int disable_bit;
277 const char *port_name;
278
279 if (serio == i8042_ports[I8042_AUX_PORT_NO].serio) {
280 irq_bit = I8042_CTR_AUXINT;
281 disable_bit = I8042_CTR_AUXDIS;
282 port_name = "AUX";
283 } else {
284 irq_bit = I8042_CTR_KBDINT;
285 disable_bit = I8042_CTR_KBDDIS;
286 port_name = "KBD";
287 }
288
289 i8042_ctr &= ~irq_bit;
290 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
291 printk(KERN_WARNING
292 "i8042.c: Can't write CTR while closing %s port.\n",
293 port_name);
294
295 udelay(50);
296
297 i8042_ctr &= ~disable_bit;
298 i8042_ctr |= irq_bit;
299 if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
300 printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n",
301 port_name);
302
303 /*
304 * See if there is any data appeared while we were messing with
305 * port state.
306 */
307 i8042_interrupt(0, NULL);
308}
309
267/* 310/*
268 * i8042_start() is called by serio core when port is about to finish 311 * i8042_start() is called by serio core when port is about to finish
269 * registering. It will mark port as existing so i8042_interrupt can 312 * registering. It will mark port as existing so i8042_interrupt can
@@ -393,7 +436,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
393} 436}
394 437
395/* 438/*
396 * i8042_enable_kbd_port enables keybaord port on chip 439 * i8042_enable_kbd_port enables keyboard port on chip
397 */ 440 */
398 441
399static int i8042_enable_kbd_port(void) 442static int i8042_enable_kbd_port(void)
@@ -841,6 +884,9 @@ static void i8042_controller_reset(void)
841 i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; 884 i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS;
842 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); 885 i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
843 886
887 if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
888 printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");
889
844/* 890/*
845 * Disable MUX mode if present. 891 * Disable MUX mode if present.
846 */ 892 */
@@ -1026,6 +1072,7 @@ static int __devinit i8042_create_kbd_port(void)
1026 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; 1072 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
1027 serio->start = i8042_start; 1073 serio->start = i8042_start;
1028 serio->stop = i8042_stop; 1074 serio->stop = i8042_stop;
1075 serio->close = i8042_port_close;
1029 serio->port_data = port; 1076 serio->port_data = port;
1030 serio->dev.parent = &i8042_platform_device->dev; 1077 serio->dev.parent = &i8042_platform_device->dev;
1031 strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); 1078 strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
@@ -1056,6 +1103,7 @@ static int __devinit i8042_create_aux_port(int idx)
1056 if (idx < 0) { 1103 if (idx < 0) {
1057 strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name)); 1104 strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
1058 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); 1105 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
1106 serio->close = i8042_port_close;
1059 } else { 1107 } else {
1060 snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx); 1108 snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
1061 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1); 1109 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);