aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio/i8042.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r--drivers/input/serio/i8042.c199
1 files changed, 118 insertions, 81 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 708a1d3beab9..40d451ce07ff 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -27,6 +27,10 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
27MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver"); 27MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver");
28MODULE_LICENSE("GPL"); 28MODULE_LICENSE("GPL");
29 29
30static unsigned int i8042_nokbd;
31module_param_named(nokbd, i8042_nokbd, bool, 0);
32MODULE_PARM_DESC(nokbd, "Do not probe or use KBD port.");
33
30static unsigned int i8042_noaux; 34static unsigned int i8042_noaux;
31module_param_named(noaux, i8042_noaux, bool, 0); 35module_param_named(noaux, i8042_noaux, bool, 0);
32MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); 36MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
@@ -338,10 +342,10 @@ static int i8042_open(struct serio *serio)
338 342
339 return 0; 343 return 0;
340 344
341activate_fail: 345 activate_fail:
342 free_irq(port->irq, i8042_request_irq_cookie); 346 free_irq(port->irq, i8042_request_irq_cookie);
343 347
344irq_fail: 348 irq_fail:
345 serio_unregister_port_delayed(serio); 349 serio_unregister_port_delayed(serio);
346 350
347 return -1; 351 return -1;
@@ -485,7 +489,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
485 serio_interrupt(port->serio, data, dfl, regs); 489 serio_interrupt(port->serio, data, dfl, regs);
486 490
487 ret = 1; 491 ret = 1;
488out: 492 out:
489 return IRQ_RETVAL(ret); 493 return IRQ_RETVAL(ret);
490} 494}
491 495
@@ -552,7 +556,7 @@ static int i8042_enable_mux_ports(void)
552 * Enable all muxed ports. 556 * Enable all muxed ports.
553 */ 557 */
554 558
555 for (i = 0; i < 4; i++) { 559 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
556 i8042_command(&param, I8042_CMD_MUX_PFX + i); 560 i8042_command(&param, I8042_CMD_MUX_PFX + i);
557 i8042_command(&param, I8042_CMD_AUX_ENABLE); 561 i8042_command(&param, I8042_CMD_AUX_ENABLE);
558 } 562 }
@@ -682,7 +686,7 @@ static int __init i8042_port_register(struct i8042_port *port)
682 kfree(port->serio); 686 kfree(port->serio);
683 port->serio = NULL; 687 port->serio = NULL;
684 i8042_ctr |= port->disable; 688 i8042_ctr |= port->disable;
685 return -1; 689 return -EIO;
686 } 690 }
687 691
688 printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n", 692 printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
@@ -977,85 +981,88 @@ static struct device_driver i8042_driver = {
977 .shutdown = i8042_shutdown, 981 .shutdown = i8042_shutdown,
978}; 982};
979 983
980static void __init i8042_create_kbd_port(void) 984static int __init i8042_create_kbd_port(void)
981{ 985{
982 struct serio *serio; 986 struct serio *serio;
983 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; 987 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
984 988
985 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 989 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
986 if (serio) { 990 if (!serio)
987 memset(serio, 0, sizeof(struct serio)); 991 return -ENOMEM;
988 serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL; 992
989 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; 993 serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
990 serio->open = i8042_open; 994 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
991 serio->close = i8042_close; 995 serio->open = i8042_open;
992 serio->start = i8042_start; 996 serio->close = i8042_close;
993 serio->stop = i8042_stop; 997 serio->start = i8042_start;
994 serio->port_data = port; 998 serio->stop = i8042_stop;
995 serio->dev.parent = &i8042_platform_device->dev; 999 serio->port_data = port;
996 strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name)); 1000 serio->dev.parent = &i8042_platform_device->dev;
997 strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); 1001 strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
998 1002 strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
999 port->serio = serio; 1003
1000 i8042_port_register(port); 1004 port->serio = serio;
1001 } 1005
1006 return i8042_port_register(port);
1002} 1007}
1003 1008
1004static void __init i8042_create_aux_port(void) 1009static int __init i8042_create_aux_port(void)
1005{ 1010{
1006 struct serio *serio; 1011 struct serio *serio;
1007 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; 1012 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
1008 1013
1009 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 1014 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
1010 if (serio) { 1015 if (!serio)
1011 memset(serio, 0, sizeof(struct serio)); 1016 return -ENOMEM;
1012 serio->id.type = SERIO_8042; 1017
1013 serio->write = i8042_aux_write; 1018 serio->id.type = SERIO_8042;
1014 serio->open = i8042_open; 1019 serio->write = i8042_aux_write;
1015 serio->close = i8042_close; 1020 serio->open = i8042_open;
1016 serio->start = i8042_start; 1021 serio->close = i8042_close;
1017 serio->stop = i8042_stop; 1022 serio->start = i8042_start;
1018 serio->port_data = port; 1023 serio->stop = i8042_stop;
1019 serio->dev.parent = &i8042_platform_device->dev; 1024 serio->port_data = port;
1020 strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name)); 1025 serio->dev.parent = &i8042_platform_device->dev;
1021 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); 1026 strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
1022 1027 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
1023 port->serio = serio; 1028
1024 i8042_port_register(port); 1029 port->serio = serio;
1025 } 1030
1031 return i8042_port_register(port);
1026} 1032}
1027 1033
1028static void __init i8042_create_mux_port(int index) 1034static int __init i8042_create_mux_port(int index)
1029{ 1035{
1030 struct serio *serio; 1036 struct serio *serio;
1031 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; 1037 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
1032 1038
1033 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 1039 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
1034 if (serio) { 1040 if (!serio)
1035 memset(serio, 0, sizeof(struct serio)); 1041 return -ENOMEM;
1036 serio->id.type = SERIO_8042; 1042
1037 serio->write = i8042_aux_write; 1043 serio->id.type = SERIO_8042;
1038 serio->open = i8042_open; 1044 serio->write = i8042_aux_write;
1039 serio->close = i8042_close; 1045 serio->open = i8042_open;
1040 serio->start = i8042_start; 1046 serio->close = i8042_close;
1041 serio->stop = i8042_stop; 1047 serio->start = i8042_start;
1042 serio->port_data = port; 1048 serio->stop = i8042_stop;
1043 serio->dev.parent = &i8042_platform_device->dev; 1049 serio->port_data = port;
1044 snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index); 1050 serio->dev.parent = &i8042_platform_device->dev;
1045 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1); 1051 snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
1046 1052 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
1047 *port = i8042_ports[I8042_AUX_PORT_NO]; 1053
1048 port->exists = 0; 1054 *port = i8042_ports[I8042_AUX_PORT_NO];
1049 snprintf(port->name, sizeof(port->name), "AUX%d", index); 1055 port->exists = 0;
1050 port->mux = index; 1056 snprintf(port->name, sizeof(port->name), "AUX%d", index);
1051 port->serio = serio; 1057 port->mux = index;
1052 i8042_port_register(port); 1058 port->serio = serio;
1053 } 1059
1060 return i8042_port_register(port);
1054} 1061}
1055 1062
1056static int __init i8042_init(void) 1063static int __init i8042_init(void)
1057{ 1064{
1058 int i; 1065 int i, have_ports = 0;
1059 int err; 1066 int err;
1060 1067
1061 dbg_init(); 1068 dbg_init();
@@ -1063,43 +1070,73 @@ static int __init i8042_init(void)
1063 init_timer(&i8042_timer); 1070 init_timer(&i8042_timer);
1064 i8042_timer.function = i8042_timer_func; 1071 i8042_timer.function = i8042_timer_func;
1065 1072
1066 if (i8042_platform_init()) 1073 err = i8042_platform_init();
1067 return -EBUSY; 1074 if (err)
1075 return err;
1068 1076
1069 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ; 1077 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1070 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ; 1078 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1071 1079
1072 if (i8042_controller_init()) { 1080 if (i8042_controller_init()) {
1073 i8042_platform_exit(); 1081 err = -ENODEV;
1074 return -ENODEV; 1082 goto err_platform_exit;
1075 } 1083 }
1076 1084
1077 err = driver_register(&i8042_driver); 1085 err = driver_register(&i8042_driver);
1078 if (err) { 1086 if (err)
1079 i8042_platform_exit(); 1087 goto err_controller_cleanup;
1080 return err;
1081 }
1082 1088
1083 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0); 1089 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
1084 if (IS_ERR(i8042_platform_device)) { 1090 if (IS_ERR(i8042_platform_device)) {
1085 driver_unregister(&i8042_driver); 1091 err = PTR_ERR(i8042_platform_device);
1086 i8042_platform_exit(); 1092 goto err_unregister_driver;
1087 return PTR_ERR(i8042_platform_device);
1088 } 1093 }
1089 1094
1090 if (!i8042_noaux && !i8042_check_aux()) { 1095 if (!i8042_noaux && !i8042_check_aux()) {
1091 if (!i8042_nomux && !i8042_check_mux()) 1096 if (!i8042_nomux && !i8042_check_mux()) {
1092 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) 1097 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
1093 i8042_create_mux_port(i); 1098 err = i8042_create_mux_port(i);
1094 else 1099 if (err)
1095 i8042_create_aux_port(); 1100 goto err_unregister_ports;
1101 }
1102 } else {
1103 err = i8042_create_aux_port();
1104 if (err)
1105 goto err_unregister_ports;
1106 }
1107 have_ports = 1;
1096 } 1108 }
1097 1109
1098 i8042_create_kbd_port(); 1110 if (!i8042_nokbd) {
1111 err = i8042_create_kbd_port();
1112 if (err)
1113 goto err_unregister_ports;
1114 have_ports = 1;
1115 }
1116
1117 if (!have_ports) {
1118 err = -ENODEV;
1119 goto err_unregister_device;
1120 }
1099 1121
1100 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); 1122 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
1101 1123
1102 return 0; 1124 return 0;
1125
1126 err_unregister_ports:
1127 for (i = 0; i < I8042_NUM_PORTS; i++)
1128 if (i8042_ports[i].serio)
1129 serio_unregister_port(i8042_ports[i].serio);
1130 err_unregister_device:
1131 platform_device_unregister(i8042_platform_device);
1132 err_unregister_driver:
1133 driver_unregister(&i8042_driver);
1134 err_controller_cleanup:
1135 i8042_controller_cleanup();
1136 err_platform_exit:
1137 i8042_platform_exit();
1138
1139 return err;
1103} 1140}
1104 1141
1105static void __exit i8042_exit(void) 1142static void __exit i8042_exit(void)