aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/ct82c710.c89
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h15
-rw-r--r--drivers/input/serio/i8042.c116
-rw-r--r--drivers/input/serio/maceps2.c68
-rw-r--r--drivers/input/serio/q40kbd.c89
5 files changed, 254 insertions, 123 deletions
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index 4da6c86b5d76..096b6a0b5cca 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -154,7 +154,7 @@ static int ct82c710_write(struct serio *port, unsigned char c)
154 * See if we can find a 82C710 device. Read mouse address. 154 * See if we can find a 82C710 device. Read mouse address.
155 */ 155 */
156 156
157static int __init ct82c710_probe(void) 157static int __init ct82c710_detect(void)
158{ 158{
159 outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */ 159 outb_p(0x55, 0x2fa); /* Any value except 9, ff or 36 */
160 outb_p(0xaa, 0x3fa); /* Inverse of 55 */ 160 outb_p(0xaa, 0x3fa); /* Inverse of 55 */
@@ -163,7 +163,7 @@ static int __init ct82c710_probe(void)
163 outb_p(0x1b, 0x2fa); /* Inverse of e4 */ 163 outb_p(0x1b, 0x2fa); /* Inverse of e4 */
164 outb_p(0x0f, 0x390); /* Write index */ 164 outb_p(0x0f, 0x390); /* Write index */
165 if (inb_p(0x391) != 0xe4) /* Config address found? */ 165 if (inb_p(0x391) != 0xe4) /* Config address found? */
166 return -1; /* No: no 82C710 here */ 166 return -ENODEV; /* No: no 82C710 here */
167 167
168 outb_p(0x0d, 0x390); /* Write index */ 168 outb_p(0x0d, 0x390); /* Write index */
169 ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */ 169 ct82c710_iores.start = inb_p(0x391) << 2; /* Get mouse I/O address */
@@ -175,51 +175,88 @@ static int __init ct82c710_probe(void)
175 return 0; 175 return 0;
176} 176}
177 177
178static struct serio * __init ct82c710_allocate_port(void) 178static int __devinit ct82c710_probe(struct platform_device *dev)
179{ 179{
180 struct serio *serio; 180 ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
181 181 if (!ct82c710_port)
182 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 182 return -ENOMEM;
183 if (serio) { 183
184 memset(serio, 0, sizeof(struct serio)); 184 ct82c710_port->id.type = SERIO_8042;
185 serio->id.type = SERIO_8042; 185 ct82c710_port->dev.parent = &dev->dev;
186 serio->open = ct82c710_open; 186 ct82c710_port->open = ct82c710_open;
187 serio->close = ct82c710_close; 187 ct82c710_port->close = ct82c710_close;
188 serio->write = ct82c710_write; 188 ct82c710_port->write = ct82c710_write;
189 serio->dev.parent = &ct82c710_device->dev; 189 strlcpy(ct82c710_port->name, "C&T 82c710 mouse port",
190 strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name)); 190 sizeof(ct82c710_port->name));
191 snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA); 191 snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
192 } 192 "isa%04lx/serio0", CT82C710_DATA);
193
194 serio_register_port(ct82c710_port);
195
196 return 0;
197}
198
199static int __devexit ct82c710_remove(struct platform_device *dev)
200{
201 serio_unregister_port(ct82c710_port);
193 202
194 return serio; 203 return 0;
195} 204}
196 205
206static struct platform_driver ct82c710_driver = {
207 .driver = {
208 .name = "ct82c710",
209 .owner = THIS_MODULE,
210 },
211 .probe = ct82c710_probe,
212 .remove = __devexit_p(ct82c710_remove),
213};
214
215
197static int __init ct82c710_init(void) 216static int __init ct82c710_init(void)
198{ 217{
199 if (ct82c710_probe()) 218 int error;
200 return -ENODEV;
201 219
202 ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1); 220 error = ct82c710_detect();
203 if (IS_ERR(ct82c710_device)) 221 if (error)
204 return PTR_ERR(ct82c710_device); 222 return error;
205 223
206 if (!(ct82c710_port = ct82c710_allocate_port())) { 224 error = platform_driver_register(&ct82c710_driver);
207 platform_device_unregister(ct82c710_device); 225 if (error)
208 return -ENOMEM; 226 return error;
227
228 ct82c710_device = platform_device_alloc("ct82c710", -1);
229 if (!ct82c710_device) {
230 error = -ENOMEM;
231 goto err_unregister_driver;
209 } 232 }
210 233
234 error = platform_device_add_resources(ct82c710_device, &ct82c710_iores, 1);
235 if (error)
236 goto err_free_device;
237
238 error = platform_device_add(ct82c710_device);
239 if (error)
240 goto err_free_device;
241
211 serio_register_port(ct82c710_port); 242 serio_register_port(ct82c710_port);
212 243
213 printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", 244 printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n",
214 CT82C710_DATA, CT82C710_IRQ); 245 CT82C710_DATA, CT82C710_IRQ);
215 246
216 return 0; 247 return 0;
248
249 err_free_device:
250 platform_device_put(ct82c710_device);
251 err_unregister_driver:
252 platform_driver_unregister(&ct82c710_driver);
253 return error;
217} 254}
218 255
219static void __exit ct82c710_exit(void) 256static void __exit ct82c710_exit(void)
220{ 257{
221 serio_unregister_port(ct82c710_port);
222 platform_device_unregister(ct82c710_device); 258 platform_device_unregister(ct82c710_device);
259 platform_driver_unregister(&ct82c710_driver);
223} 260}
224 261
225module_init(ct82c710_init); 262module_init(ct82c710_init);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 273bb3b08cfa..2d2f9fb3aded 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -84,6 +84,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
84 DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), 84 DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
85 }, 85 },
86 }, 86 },
87 {
88 .ident = "OQO Model 01",
89 .matches = {
90 DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
91 DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
92 DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
93 },
94 },
87 { } 95 { }
88}; 96};
89 97
@@ -158,6 +166,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
158 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), 166 DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
159 }, 167 },
160 }, 168 },
169 {
170 .ident = "Sharp Actius MM20",
171 .matches = {
172 DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
173 DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
174 },
175 },
161 { } 176 { }
162}; 177};
163 178
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index ac86c1d1d83e..a7d91d5356a5 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -572,7 +572,7 @@ static int i8042_enable_mux_ports(void)
572 * LCS/Telegraphics. 572 * LCS/Telegraphics.
573 */ 573 */
574 574
575static int __init i8042_check_mux(void) 575static int __devinit i8042_check_mux(void)
576{ 576{
577 unsigned char mux_version; 577 unsigned char mux_version;
578 578
@@ -600,7 +600,7 @@ static int __init i8042_check_mux(void)
600 * the presence of an AUX interface. 600 * the presence of an AUX interface.
601 */ 601 */
602 602
603static int __init i8042_check_aux(void) 603static int __devinit i8042_check_aux(void)
604{ 604{
605 unsigned char param; 605 unsigned char param;
606 static int i8042_check_aux_cookie; 606 static int i8042_check_aux_cookie;
@@ -678,7 +678,7 @@ static int __init i8042_check_aux(void)
678 * registers it, and reports to the user. 678 * registers it, and reports to the user.
679 */ 679 */
680 680
681static int __init i8042_port_register(struct i8042_port *port) 681static int __devinit i8042_port_register(struct i8042_port *port)
682{ 682{
683 i8042_ctr &= ~port->disable; 683 i8042_ctr &= ~port->disable;
684 684
@@ -956,7 +956,6 @@ static int i8042_resume(struct platform_device *dev)
956 panic_blink = i8042_panic_blink; 956 panic_blink = i8042_panic_blink;
957 957
958 return 0; 958 return 0;
959
960} 959}
961 960
962/* 961/*
@@ -969,16 +968,7 @@ static void i8042_shutdown(struct platform_device *dev)
969 i8042_controller_cleanup(); 968 i8042_controller_cleanup();
970} 969}
971 970
972static struct platform_driver i8042_driver = { 971static int __devinit i8042_create_kbd_port(void)
973 .suspend = i8042_suspend,
974 .resume = i8042_resume,
975 .shutdown = i8042_shutdown,
976 .driver = {
977 .name = "i8042",
978 },
979};
980
981static int __init i8042_create_kbd_port(void)
982{ 972{
983 struct serio *serio; 973 struct serio *serio;
984 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; 974 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1003,7 +993,7 @@ static int __init i8042_create_kbd_port(void)
1003 return i8042_port_register(port); 993 return i8042_port_register(port);
1004} 994}
1005 995
1006static int __init i8042_create_aux_port(void) 996static int __devinit i8042_create_aux_port(void)
1007{ 997{
1008 struct serio *serio; 998 struct serio *serio;
1009 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO]; 999 struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
@@ -1028,7 +1018,7 @@ static int __init i8042_create_aux_port(void)
1028 return i8042_port_register(port); 1018 return i8042_port_register(port);
1029} 1019}
1030 1020
1031static int __init i8042_create_mux_port(int index) 1021static int __devinit i8042_create_mux_port(int index)
1032{ 1022{
1033 struct serio *serio; 1023 struct serio *serio;
1034 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index]; 1024 struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
@@ -1057,37 +1047,16 @@ static int __init i8042_create_mux_port(int index)
1057 return i8042_port_register(port); 1047 return i8042_port_register(port);
1058} 1048}
1059 1049
1060static int __init i8042_init(void) 1050static int __devinit i8042_probe(struct platform_device *dev)
1061{ 1051{
1062 int i, have_ports = 0; 1052 int i, have_ports = 0;
1063 int err; 1053 int err;
1064 1054
1065 dbg_init();
1066
1067 init_timer(&i8042_timer); 1055 init_timer(&i8042_timer);
1068 i8042_timer.function = i8042_timer_func; 1056 i8042_timer.function = i8042_timer_func;
1069 1057
1070 err = i8042_platform_init(); 1058 if (i8042_controller_init())
1071 if (err) 1059 return -ENODEV;
1072 return err;
1073
1074 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1075 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1076
1077 if (i8042_controller_init()) {
1078 err = -ENODEV;
1079 goto err_platform_exit;
1080 }
1081
1082 err = platform_driver_register(&i8042_driver);
1083 if (err)
1084 goto err_controller_cleanup;
1085
1086 i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
1087 if (IS_ERR(i8042_platform_device)) {
1088 err = PTR_ERR(i8042_platform_device);
1089 goto err_unregister_driver;
1090 }
1091 1060
1092 if (!i8042_noaux && !i8042_check_aux()) { 1061 if (!i8042_noaux && !i8042_check_aux()) {
1093 if (!i8042_nomux && !i8042_check_mux()) { 1062 if (!i8042_nomux && !i8042_check_mux()) {
@@ -1113,30 +1082,23 @@ static int __init i8042_init(void)
1113 1082
1114 if (!have_ports) { 1083 if (!have_ports) {
1115 err = -ENODEV; 1084 err = -ENODEV;
1116 goto err_unregister_device; 1085 goto err_controller_cleanup;
1117 } 1086 }
1118 1087
1119 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); 1088 mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
1120
1121 return 0; 1089 return 0;
1122 1090
1123 err_unregister_ports: 1091 err_unregister_ports:
1124 for (i = 0; i < I8042_NUM_PORTS; i++) 1092 for (i = 0; i < I8042_NUM_PORTS; i++)
1125 if (i8042_ports[i].serio) 1093 if (i8042_ports[i].serio)
1126 serio_unregister_port(i8042_ports[i].serio); 1094 serio_unregister_port(i8042_ports[i].serio);
1127 err_unregister_device:
1128 platform_device_unregister(i8042_platform_device);
1129 err_unregister_driver:
1130 platform_driver_unregister(&i8042_driver);
1131 err_controller_cleanup: 1095 err_controller_cleanup:
1132 i8042_controller_cleanup(); 1096 i8042_controller_cleanup();
1133 err_platform_exit:
1134 i8042_platform_exit();
1135 1097
1136 return err; 1098 return err;
1137} 1099}
1138 1100
1139static void __exit i8042_exit(void) 1101static int __devexit i8042_remove(struct platform_device *dev)
1140{ 1102{
1141 int i; 1103 int i;
1142 1104
@@ -1148,6 +1110,62 @@ static void __exit i8042_exit(void)
1148 1110
1149 del_timer_sync(&i8042_timer); 1111 del_timer_sync(&i8042_timer);
1150 1112
1113 return 0;
1114}
1115
1116static struct platform_driver i8042_driver = {
1117 .driver = {
1118 .name = "i8042",
1119 .owner = THIS_MODULE,
1120 },
1121 .probe = i8042_probe,
1122 .remove = __devexit_p(i8042_remove),
1123 .suspend = i8042_suspend,
1124 .resume = i8042_resume,
1125 .shutdown = i8042_shutdown,
1126};
1127
1128static int __init i8042_init(void)
1129{
1130 int err;
1131
1132 dbg_init();
1133
1134 err = i8042_platform_init();
1135 if (err)
1136 return err;
1137
1138 i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
1139 i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
1140
1141 err = platform_driver_register(&i8042_driver);
1142 if (err)
1143 goto err_platform_exit;
1144
1145 i8042_platform_device = platform_device_alloc("i8042", -1);
1146 if (!i8042_platform_device) {
1147 err = -ENOMEM;
1148 goto err_unregister_driver;
1149 }
1150
1151 err = platform_device_add(i8042_platform_device);
1152 if (err)
1153 goto err_free_device;
1154
1155 return 0;
1156
1157 err_free_device:
1158 platform_device_put(i8042_platform_device);
1159 err_unregister_driver:
1160 platform_driver_unregister(&i8042_driver);
1161 err_platform_exit:
1162 i8042_platform_exit();
1163
1164 return err;
1165}
1166
1167static void __exit i8042_exit(void)
1168{
1151 platform_device_unregister(i8042_platform_device); 1169 platform_device_unregister(i8042_platform_device);
1152 platform_driver_unregister(&i8042_driver); 1170 platform_driver_unregister(&i8042_driver);
1153 1171
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index d857f7081adb..f08a5d0cd5fa 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -118,13 +118,12 @@ static void maceps2_close(struct serio *dev)
118} 118}
119 119
120 120
121static struct serio * __init maceps2_allocate_port(int idx) 121static struct serio * __devinit maceps2_allocate_port(int idx)
122{ 122{
123 struct serio *serio; 123 struct serio *serio;
124 124
125 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 125 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
126 if (serio) { 126 if (serio) {
127 memset(serio, 0, sizeof(struct serio));
128 serio->id.type = SERIO_8042; 127 serio->id.type = SERIO_8042;
129 serio->write = maceps2_write; 128 serio->write = maceps2_write;
130 serio->open = maceps2_open; 129 serio->open = maceps2_open;
@@ -138,24 +137,13 @@ static struct serio * __init maceps2_allocate_port(int idx)
138 return serio; 137 return serio;
139} 138}
140 139
141 140static int __devinit maceps2_probe(struct platform_device *dev)
142static int __init maceps2_init(void)
143{ 141{
144 maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0);
145 if (IS_ERR(maceps2_device))
146 return PTR_ERR(maceps2_device);
147
148 port_data[0].port = &mace->perif.ps2.keyb;
149 port_data[0].irq = MACEISA_KEYB_IRQ;
150 port_data[1].port = &mace->perif.ps2.mouse;
151 port_data[1].irq = MACEISA_MOUSE_IRQ;
152
153 maceps2_port[0] = maceps2_allocate_port(0); 142 maceps2_port[0] = maceps2_allocate_port(0);
154 maceps2_port[1] = maceps2_allocate_port(1); 143 maceps2_port[1] = maceps2_allocate_port(1);
155 if (!maceps2_port[0] || !maceps2_port[1]) { 144 if (!maceps2_port[0] || !maceps2_port[1]) {
156 kfree(maceps2_port[0]); 145 kfree(maceps2_port[0]);
157 kfree(maceps2_port[1]); 146 kfree(maceps2_port[1]);
158 platform_device_unregister(maceps2_device);
159 return -ENOMEM; 147 return -ENOMEM;
160 } 148 }
161 149
@@ -165,11 +153,59 @@ static int __init maceps2_init(void)
165 return 0; 153 return 0;
166} 154}
167 155
168static void __exit maceps2_exit(void) 156static int __devexit maceps2_remove(struct platform_device *dev)
169{ 157{
170 serio_unregister_port(maceps2_port[0]); 158 serio_unregister_port(maceps2_port[0]);
171 serio_unregister_port(maceps2_port[1]); 159 serio_unregister_port(maceps2_port[1]);
160
161 return 0;
162}
163
164static struct platform_driver maceps2_driver = {
165 .driver = {
166 .name = "maceps2",
167 .owner = THIS_MODULE,
168 },
169 .probe = maceps2_probe,
170 .remove = __devexit_p(maceps2_remove),
171};
172
173static int __init maceps2_init(void)
174{
175 int error;
176
177 error = platform_driver_register(&maceps2_driver);
178 if (error)
179 return error;
180
181 maceps2_device = platform_device_alloc("maceps2", -1);
182 if (!maceps2_device) {
183 error = -ENOMEM;
184 goto err_unregister_driver;
185 }
186
187 port_data[0].port = &mace->perif.ps2.keyb;
188 port_data[0].irq = MACEISA_KEYB_IRQ;
189 port_data[1].port = &mace->perif.ps2.mouse;
190 port_data[1].irq = MACEISA_MOUSE_IRQ;
191
192 error = platform_device_add(maceps2_device);
193 if (error)
194 goto err_free_device;
195
196 return 0;
197
198 err_free_device:
199 platform_device_put(maceps2_device);
200 err_unregister_driver:
201 platform_driver_unregister(&maceps2_driver);
202 return error;
203}
204
205static void __exit maceps2_exit(void)
206{
172 platform_device_unregister(maceps2_device); 207 platform_device_unregister(maceps2_device);
208 platform_driver_unregister(&maceps2_driver);
173} 209}
174 210
175module_init(maceps2_init); 211module_init(maceps2_init);
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index b44d255596c2..d3827c5fe119 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -75,13 +75,13 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
75 75
76static void q40kbd_flush(void) 76static void q40kbd_flush(void)
77{ 77{
78 int maxread = 100; 78 int maxread = 100;
79 unsigned long flags; 79 unsigned long flags;
80 80
81 spin_lock_irqsave(&q40kbd_lock, flags); 81 spin_lock_irqsave(&q40kbd_lock, flags);
82 82
83 while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) 83 while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
84 master_inb(KEYCODE_REG); 84 master_inb(KEYCODE_REG);
85 85
86 spin_unlock_irqrestore(&q40kbd_lock, flags); 86 spin_unlock_irqrestore(&q40kbd_lock, flags);
87} 87}
@@ -97,14 +97,14 @@ static int q40kbd_open(struct serio *port)
97 97
98 if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { 98 if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
99 printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); 99 printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
100 return -1; 100 return -EBUSY;
101 } 101 }
102 102
103 /* off we go */ 103 /* off we go */
104 master_outb(-1, KEYBOARD_UNLOCK_REG); 104 master_outb(-1, KEYBOARD_UNLOCK_REG);
105 master_outb(1, KEY_IRQ_ENABLE_REG); 105 master_outb(1, KEY_IRQ_ENABLE_REG);
106 106
107 return 0; 107 return 0;
108} 108}
109 109
110static void q40kbd_close(struct serio *port) 110static void q40kbd_close(struct serio *port)
@@ -116,48 +116,73 @@ static void q40kbd_close(struct serio *port)
116 q40kbd_flush(); 116 q40kbd_flush();
117} 117}
118 118
119static struct serio * __init q40kbd_allocate_port(void) 119static int __devinit q40kbd_probe(struct platform_device *dev)
120{ 120{
121 struct serio *serio; 121 q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
122 122 if (!q40kbd_port)
123 serio = kmalloc(sizeof(struct serio), GFP_KERNEL); 123 return -ENOMEM;
124 if (serio) { 124
125 memset(serio, 0, sizeof(struct serio)); 125 q40kbd_port->id.type = SERIO_8042;
126 serio->id.type = SERIO_8042; 126 q40kbd_port->open = q40kbd_open;
127 serio->open = q40kbd_open; 127 q40kbd_port->close = q40kbd_close;
128 serio->close = q40kbd_close; 128 q40kbd_port->dev.parent = &dev->dev;
129 serio->dev.parent = &q40kbd_device->dev; 129 strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name));
130 strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name)); 130 strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys));
131 strlcpy(serio->phys, "Q40", sizeof(serio->phys)); 131
132 } 132 serio_register_port(q40kbd_port);
133 printk(KERN_INFO "serio: Q40 kbd registered\n");
133 134
134 return serio; 135 return 0;
135} 136}
136 137
138static int __devexit q40kbd_remove(struct platform_device *dev)
139{
140 serio_unregister_port(q40kbd_port);
141
142 return 0;
143}
144
145static struct platform_driver q40kbd_driver = {
146 .driver = {
147 .name = "q40kbd",
148 .owner = THIS_MODULE,
149 },
150 .probe = q40kbd_probe,
151 .remove = __devexit_p(q40kbd_remove),
152};
153
137static int __init q40kbd_init(void) 154static int __init q40kbd_init(void)
138{ 155{
156 int error;
157
139 if (!MACH_IS_Q40) 158 if (!MACH_IS_Q40)
140 return -EIO; 159 return -EIO;
141 160
142 q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0); 161 error = platform_driver_register(&q40kbd_driver);
143 if (IS_ERR(q40kbd_device)) 162 if (error)
144 return PTR_ERR(q40kbd_device); 163 return error;
145 164
146 if (!(q40kbd_port = q40kbd_allocate_port())) { 165 q40kbd_device = platform_device_alloc("q40kbd", -1);
147 platform_device_unregister(q40kbd_device); 166 if (!q40kbd_device)
148 return -ENOMEM; 167 goto err_unregister_driver;
149 }
150 168
151 serio_register_port(q40kbd_port); 169 error = platform_device_add(q40kbd_device);
152 printk(KERN_INFO "serio: Q40 kbd registered\n"); 170 if (error)
171 goto err_free_device;
153 172
154 return 0; 173 return 0;
174
175 err_free_device:
176 platform_device_put(q40kbd_device);
177 err_unregister_driver:
178 platform_driver_unregister(&q40kbd_driver);
179 return error;
155} 180}
156 181
157static void __exit q40kbd_exit(void) 182static void __exit q40kbd_exit(void)
158{ 183{
159 serio_unregister_port(q40kbd_port);
160 platform_device_unregister(q40kbd_device); 184 platform_device_unregister(q40kbd_device);
185 platform_driver_unregister(&q40kbd_driver);
161} 186}
162 187
163module_init(q40kbd_init); 188module_init(q40kbd_init);