aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor_core@ameritech.net>2005-09-04 02:41:27 -0400
committerDmitry Torokhov <dtor_core@ameritech.net>2005-09-04 02:41:27 -0400
commit0854e52d86080c1043bc8988daef2ebda4775f64 (patch)
treec75b3d7f50f04c0c8e4dfd5ec6230e8d6164b672 /drivers/input/serio
parent4cee99564db7f65a6f88e4b752da52768cde3802 (diff)
Input: i8042 - clean up initialization code; abort if we
can't create all ports. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/i8042.c178
1 files changed, 100 insertions, 78 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 708a1d3beab9..f0d9c5f9cc36 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -338,10 +338,10 @@ static int i8042_open(struct serio *serio)
338 338
339 return 0; 339 return 0;
340 340
341activate_fail: 341 activate_fail:
342 free_irq(port->irq, i8042_request_irq_cookie); 342 free_irq(port->irq, i8042_request_irq_cookie);
343 343
344irq_fail: 344 irq_fail:
345 serio_unregister_port_delayed(serio); 345 serio_unregister_port_delayed(serio);
346 346
347 return -1; 347 return -1;
@@ -485,7 +485,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
485 serio_interrupt(port->serio, data, dfl, regs); 485 serio_interrupt(port->serio, data, dfl, regs);
486 486
487 ret = 1; 487 ret = 1;
488out: 488 out:
489 return IRQ_RETVAL(ret); 489 return IRQ_RETVAL(ret);
490} 490}
491 491
@@ -552,7 +552,7 @@ static int i8042_enable_mux_ports(void)
552 * Enable all muxed ports. 552 * Enable all muxed ports.
553 */ 553 */
554 554
555 for (i = 0; i < 4; i++) { 555 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
556 i8042_command(&param, I8042_CMD_MUX_PFX + i); 556 i8042_command(&param, I8042_CMD_MUX_PFX + i);
557 i8042_command(&param, I8042_CMD_AUX_ENABLE); 557 i8042_command(&param, I8042_CMD_AUX_ENABLE);
558 } 558 }
@@ -682,7 +682,7 @@ static int __init i8042_port_register(struct i8042_port *port)
682 kfree(port->serio); 682 kfree(port->serio);
683 port->serio = NULL; 683 port->serio = NULL;
684 i8042_ctr |= port->disable; 684 i8042_ctr |= port->disable;
685 return -1; 685 return -EIO;
686 } 686 }
687 687
688 printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n", 688 printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
@@ -977,80 +977,83 @@ static struct device_driver i8042_driver = {
977 .shutdown = i8042_shutdown, 977 .shutdown = i8042_shutdown,
978}; 978};
979 979
980static void __init i8042_create_kbd_port(void) 980static int __init i8042_create_kbd_port(void)
981{ 981{
982 struct serio *serio; 982 struct serio *serio;
983 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; 983 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
984 984
985 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 985 serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
986 if (serio) { 986 if (!serio)
987 memset(serio, 0, sizeof(struct serio)); 987 return -ENOMEM;
988 serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL; 988
989 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; 989 serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
990 serio->open = i8042_open; 990 serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
991 serio->close = i8042_close; 991 serio->open = i8042_open;
992 serio->start = i8042_start; 992 serio->close = i8042_close;
993 serio->stop = i8042_stop; 993 serio->start = i8042_start;
994 serio->port_data = port; 994 serio->stop = i8042_stop;
995 serio->dev.parent = &i8042_platform_device->dev; 995 serio->port_data = port;
996 strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name)); 996 serio->dev.parent = &i8042_platform_device->dev;
997 strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); 997 strlcpy(serio->name, "i8042 Kbd Port", sizeof(serio->name));
998 998 strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys));
999 port->serio = serio; 999
1000 i8042_port_register(port); 1000 port->serio = serio;
1001 } 1001
1002 return i8042_port_register(port);
1002} 1003}
1003 1004
1004static void __init i8042_create_aux_port(void) 1005static int __init i8042_create_aux_port(void)
1005{ 1006{
1006 struct serio *serio; 1007 struct serio *serio;
1007 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; 1008 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
1008 1009
1009 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 1010 serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
1010 if (serio) { 1011 if (!serio)
1011 memset(serio, 0, sizeof(struct serio)); 1012 return -ENOMEM;
1012 serio->id.type = SERIO_8042; 1013
1013 serio->write = i8042_aux_write; 1014 serio->id.type = SERIO_8042;
1014 serio->open = i8042_open; 1015 serio->write = i8042_aux_write;
1015 serio->close = i8042_close; 1016 serio->open = i8042_open;
1016 serio->start = i8042_start; 1017 serio->close = i8042_close;
1017 serio->stop = i8042_stop; 1018 serio->start = i8042_start;
1018 serio->port_data = port; 1019 serio->stop = i8042_stop;
1019 serio->dev.parent = &i8042_platform_device->dev; 1020 serio->port_data = port;
1020 strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name)); 1021 serio->dev.parent = &i8042_platform_device->dev;
1021 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); 1022 strlcpy(serio->name, "i8042 Aux Port", sizeof(serio->name));
1022 1023 strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
1023 port->serio = serio; 1024
1024 i8042_port_register(port); 1025 port->serio = serio;
1025 } 1026
1027 return i8042_port_register(port);
1026} 1028}
1027 1029
1028static void __init i8042_create_mux_port(int index) 1030static int __init i8042_create_mux_port(int index)
1029{ 1031{
1030 struct serio *serio; 1032 struct serio *serio;
1031 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; 1033 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
1032 1034
1033 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 1035 serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL);
1034 if (serio) { 1036 if (!serio)
1035 memset(serio, 0, sizeof(struct serio)); 1037 return -ENOMEM;
1036 serio->id.type = SERIO_8042; 1038
1037 serio->write = i8042_aux_write; 1039 serio->id.type = SERIO_8042;
1038 serio->open = i8042_open; 1040 serio->write = i8042_aux_write;
1039 serio->close = i8042_close; 1041 serio->open = i8042_open;
1040 serio->start = i8042_start; 1042 serio->close = i8042_close;
1041 serio->stop = i8042_stop; 1043 serio->start = i8042_start;
1042 serio->port_data = port; 1044 serio->stop = i8042_stop;
1043 serio->dev.parent = &i8042_platform_device->dev; 1045 serio->port_data = port;
1044 snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index); 1046 serio->dev.parent = &i8042_platform_device->dev;
1045 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1); 1047 snprintf(serio->name, sizeof(serio->name), "i8042 Aux-%d Port", index);
1046 1048 snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, index + 1);
1047 *port = i8042_ports[I8042_AUX_PORT_NO]; 1049
1048 port->exists = 0; 1050 *port = i8042_ports[I8042_AUX_PORT_NO];
1049 snprintf(port->name, sizeof(port->name), "AUX%d", index); 1051 port->exists = 0;
1050 port->mux = index; 1052 snprintf(port->name, sizeof(port->name), "AUX%d", index);
1051 port->serio = serio; 1053 port->mux = index;
1052 i8042_port_register(port); 1054 port->serio = serio;
1053 } 1055
1056 return i8042_port_register(port);
1054} 1057}
1055 1058
1056static int __init i8042_init(void) 1059static int __init i8042_init(void)
@@ -1070,36 +1073,55 @@ static int __init i8042_init(void)
1070 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ; 1073 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1071 1074
1072 if (i8042_controller_init()) { 1075 if (i8042_controller_init()) {
1073 i8042_platform_exit(); 1076 err = -ENODEV;
1074 return -ENODEV; 1077 goto err_platform_exit;
1075 } 1078 }
1076 1079
1077 err = driver_register(&i8042_driver); 1080 err = driver_register(&i8042_driver);
1078 if (err) { 1081 if (err)
1079 i8042_platform_exit(); 1082 goto err_controller_cleanup;
1080 return err;
1081 }
1082 1083
1083 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0); 1084 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
1084 if (IS_ERR(i8042_platform_device)) { 1085 if (IS_ERR(i8042_platform_device)) {
1085 driver_unregister(&i8042_driver); 1086 err = PTR_ERR(i8042_platform_device);
1086 i8042_platform_exit(); 1087 goto err_unregister_driver;
1087 return PTR_ERR(i8042_platform_device);
1088 } 1088 }
1089 1089
1090 if (!i8042_noaux && !i8042_check_aux()) { 1090 if (!i8042_noaux && !i8042_check_aux()) {
1091 if (!i8042_nomux && !i8042_check_mux()) 1091 if (!i8042_nomux && !i8042_check_mux()) {
1092 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) 1092 for (i = 0; i < I8042_NUM_MUX_PORTS; i++) {
1093 i8042_create_mux_port(i); 1093 err = i8042_create_mux_port(i);
1094 else 1094 if (err)
1095 i8042_create_aux_port(); 1095 goto err_unregister_ports;
1096 }
1097 } else {
1098 err = i8042_create_aux_port();
1099 if (err)
1100 goto err_unregister_ports;
1101 }
1096 } 1102 }
1097 1103
1098 i8042_create_kbd_port(); 1104 err = i8042_create_kbd_port();
1105 if (err)
1106 goto err_unregister_ports;
1099 1107
1100 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); 1108 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
1101 1109
1102 return 0; 1110 return 0;
1111
1112 err_unregister_ports:
1113 for (i = 0; i < I8042_NUM_PORTS; i++)
1114 if (i8042_ports[i].serio)
1115 serio_unregister_port(i8042_ports[i].serio);
1116 platform_device_unregister(i8042_platform_device);
1117 err_unregister_driver:
1118 driver_unregister(&i8042_driver);
1119 err_controller_cleanup:
1120 i8042_controller_cleanup();
1121 err_platform_exit:
1122 i8042_platform_exit();
1123
1124 return err;
1103} 1125}
1104 1126
1105static void __exit i8042_exit(void) 1127static void __exit i8042_exit(void)