Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * i8042 keyboard and mouse controller driver for Linux | |
3 | * | |
4 | * Copyright (c) 1999-2004 Vojtech Pavlik | |
5 | */ | |
6 | ||
7 | /* | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License version 2 as published by | |
10 | * the Free Software Foundation. | |
11 | */ | |
12 | ||
13 | #include <linux/delay.h> | |
14 | #include <linux/module.h> | |
15 | #include <linux/moduleparam.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/ioport.h> | |
1da177e4 LT |
18 | #include <linux/init.h> |
19 | #include <linux/serio.h> | |
20 | #include <linux/err.h> | |
21 | #include <linux/rcupdate.h> | |
d052d1be | 22 | #include <linux/platform_device.h> |
1da177e4 LT |
23 | |
24 | #include <asm/io.h> | |
25 | ||
26 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | |
27 | MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver"); | |
28 | MODULE_LICENSE("GPL"); | |
29 | ||
945ef0d4 DT |
30 | static unsigned int i8042_nokbd; |
31 | module_param_named(nokbd, i8042_nokbd, bool, 0); | |
32 | MODULE_PARM_DESC(nokbd, "Do not probe or use KBD port."); | |
33 | ||
1da177e4 LT |
34 | static unsigned int i8042_noaux; |
35 | module_param_named(noaux, i8042_noaux, bool, 0); | |
36 | MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); | |
37 | ||
38 | static unsigned int i8042_nomux; | |
39 | module_param_named(nomux, i8042_nomux, bool, 0); | |
40 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); | |
41 | ||
42 | static unsigned int i8042_unlock; | |
43 | module_param_named(unlock, i8042_unlock, bool, 0); | |
44 | MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); | |
45 | ||
46 | static unsigned int i8042_reset; | |
47 | module_param_named(reset, i8042_reset, bool, 0); | |
48 | MODULE_PARM_DESC(reset, "Reset controller during init and cleanup."); | |
49 | ||
50 | static unsigned int i8042_direct; | |
51 | module_param_named(direct, i8042_direct, bool, 0); | |
52 | MODULE_PARM_DESC(direct, "Put keyboard port into non-translated mode."); | |
53 | ||
54 | static unsigned int i8042_dumbkbd; | |
55 | module_param_named(dumbkbd, i8042_dumbkbd, bool, 0); | |
56 | MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard"); | |
57 | ||
58 | static unsigned int i8042_noloop; | |
59 | module_param_named(noloop, i8042_noloop, bool, 0); | |
60 | MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); | |
61 | ||
62 | static unsigned int i8042_blink_frequency = 500; | |
63 | module_param_named(panicblink, i8042_blink_frequency, uint, 0600); | |
64 | MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); | |
65 | ||
66 | #ifdef CONFIG_PNP | |
67 | static int i8042_nopnp; | |
68 | module_param_named(nopnp, i8042_nopnp, bool, 0); | |
69 | MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); | |
70 | #endif | |
71 | ||
72 | #define DEBUG | |
73 | #ifdef DEBUG | |
74 | static int i8042_debug; | |
75 | module_param_named(debug, i8042_debug, bool, 0600); | |
76 | MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); | |
77 | #endif | |
78 | ||
79 | __obsolete_setup("i8042_noaux"); | |
80 | __obsolete_setup("i8042_nomux"); | |
81 | __obsolete_setup("i8042_unlock"); | |
82 | __obsolete_setup("i8042_reset"); | |
83 | __obsolete_setup("i8042_direct"); | |
84 | __obsolete_setup("i8042_dumbkbd"); | |
85 | ||
86 | #include "i8042.h" | |
87 | ||
88 | static DEFINE_SPINLOCK(i8042_lock); | |
89 | ||
90 | struct i8042_port { | |
91 | struct serio *serio; | |
92 | int irq; | |
1da177e4 LT |
93 | unsigned char exists; |
94 | signed char mux; | |
1da177e4 LT |
95 | }; |
96 | ||
97 | #define I8042_KBD_PORT_NO 0 | |
98 | #define I8042_AUX_PORT_NO 1 | |
99 | #define I8042_MUX_PORT_NO 2 | |
100 | #define I8042_NUM_PORTS (I8042_NUM_MUX_PORTS + 2) | |
de9ce703 DT |
101 | |
102 | static struct i8042_port i8042_ports[I8042_NUM_PORTS]; | |
1da177e4 LT |
103 | |
104 | static unsigned char i8042_initial_ctr; | |
105 | static unsigned char i8042_ctr; | |
1da177e4 | 106 | static unsigned char i8042_mux_present; |
de9ce703 DT |
107 | static unsigned char i8042_kbd_irq_registered; |
108 | static unsigned char i8042_aux_irq_registered; | |
1da177e4 LT |
109 | static struct platform_device *i8042_platform_device; |
110 | ||
1da177e4 LT |
111 | static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
112 | ||
113 | /* | |
114 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to | |
115 | * be ready for reading values from it / writing values to it. | |
116 | * Called always with i8042_lock held. | |
117 | */ | |
118 | ||
119 | static int i8042_wait_read(void) | |
120 | { | |
121 | int i = 0; | |
de9ce703 | 122 | |
1da177e4 LT |
123 | while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) { |
124 | udelay(50); | |
125 | i++; | |
126 | } | |
127 | return -(i == I8042_CTL_TIMEOUT); | |
128 | } | |
129 | ||
130 | static int i8042_wait_write(void) | |
131 | { | |
132 | int i = 0; | |
de9ce703 | 133 | |
1da177e4 LT |
134 | while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) { |
135 | udelay(50); | |
136 | i++; | |
137 | } | |
138 | return -(i == I8042_CTL_TIMEOUT); | |
139 | } | |
140 | ||
141 | /* | |
142 | * i8042_flush() flushes all data that may be in the keyboard and mouse buffers | |
143 | * of the i8042 down the toilet. | |
144 | */ | |
145 | ||
146 | static int i8042_flush(void) | |
147 | { | |
148 | unsigned long flags; | |
149 | unsigned char data, str; | |
150 | int i = 0; | |
151 | ||
152 | spin_lock_irqsave(&i8042_lock, flags); | |
153 | ||
154 | while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) { | |
155 | udelay(50); | |
156 | data = i8042_read_data(); | |
157 | i++; | |
158 | dbg("%02x <- i8042 (flush, %s)", data, | |
159 | str & I8042_STR_AUXDATA ? "aux" : "kbd"); | |
160 | } | |
161 | ||
162 | spin_unlock_irqrestore(&i8042_lock, flags); | |
163 | ||
164 | return i; | |
165 | } | |
166 | ||
167 | /* | |
168 | * i8042_command() executes a command on the i8042. It also sends the input | |
169 | * parameter(s) of the commands to it, and receives the output value(s). The | |
170 | * parameters are to be stored in the param array, and the output is placed | |
171 | * into the same array. The number of the parameters and output values is | |
172 | * encoded in bits 8-11 of the command number. | |
173 | */ | |
174 | ||
de9ce703 | 175 | static int __i8042_command(unsigned char *param, int command) |
1da177e4 | 176 | { |
de9ce703 | 177 | int i, error; |
1da177e4 LT |
178 | |
179 | if (i8042_noloop && command == I8042_CMD_AUX_LOOP) | |
180 | return -1; | |
181 | ||
de9ce703 DT |
182 | error = i8042_wait_write(); |
183 | if (error) | |
184 | return error; | |
463a4f76 DT |
185 | |
186 | dbg("%02x -> i8042 (command)", command & 0xff); | |
187 | i8042_write_command(command & 0xff); | |
188 | ||
189 | for (i = 0; i < ((command >> 12) & 0xf); i++) { | |
de9ce703 DT |
190 | error = i8042_wait_write(); |
191 | if (error) | |
192 | return error; | |
463a4f76 DT |
193 | dbg("%02x -> i8042 (parameter)", param[i]); |
194 | i8042_write_data(param[i]); | |
1da177e4 LT |
195 | } |
196 | ||
463a4f76 | 197 | for (i = 0; i < ((command >> 8) & 0xf); i++) { |
de9ce703 DT |
198 | error = i8042_wait_read(); |
199 | if (error) { | |
200 | dbg(" -- i8042 (timeout)"); | |
201 | return error; | |
202 | } | |
1da177e4 | 203 | |
463a4f76 DT |
204 | if (command == I8042_CMD_AUX_LOOP && |
205 | !(i8042_read_status() & I8042_STR_AUXDATA)) { | |
de9ce703 DT |
206 | dbg(" -- i8042 (auxerr)"); |
207 | return -1; | |
1da177e4 LT |
208 | } |
209 | ||
463a4f76 DT |
210 | param[i] = i8042_read_data(); |
211 | dbg("%02x <- i8042 (return)", param[i]); | |
212 | } | |
1da177e4 | 213 | |
de9ce703 DT |
214 | return 0; |
215 | } | |
1da177e4 | 216 | |
de9ce703 DT |
217 | static int i8042_command(unsigned char *param, int command) |
218 | { | |
219 | unsigned long flags; | |
220 | int retval; | |
221 | ||
222 | spin_lock_irqsave(&i8042_lock, flags); | |
223 | retval = __i8042_command(param, command); | |
463a4f76 | 224 | spin_unlock_irqrestore(&i8042_lock, flags); |
de9ce703 | 225 | |
1da177e4 LT |
226 | return retval; |
227 | } | |
228 | ||
229 | /* | |
230 | * i8042_kbd_write() sends a byte out through the keyboard interface. | |
231 | */ | |
232 | ||
233 | static int i8042_kbd_write(struct serio *port, unsigned char c) | |
234 | { | |
235 | unsigned long flags; | |
236 | int retval = 0; | |
237 | ||
238 | spin_lock_irqsave(&i8042_lock, flags); | |
239 | ||
de9ce703 | 240 | if (!(retval = i8042_wait_write())) { |
1da177e4 LT |
241 | dbg("%02x -> i8042 (kbd-data)", c); |
242 | i8042_write_data(c); | |
243 | } | |
244 | ||
245 | spin_unlock_irqrestore(&i8042_lock, flags); | |
246 | ||
247 | return retval; | |
248 | } | |
249 | ||
250 | /* | |
251 | * i8042_aux_write() sends a byte out through the aux interface. | |
252 | */ | |
253 | ||
254 | static int i8042_aux_write(struct serio *serio, unsigned char c) | |
255 | { | |
256 | struct i8042_port *port = serio->port_data; | |
257 | int retval; | |
258 | ||
259 | /* | |
260 | * Send the byte out. | |
261 | */ | |
262 | ||
263 | if (port->mux == -1) | |
264 | retval = i8042_command(&c, I8042_CMD_AUX_SEND); | |
265 | else | |
266 | retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux); | |
267 | ||
268 | /* | |
269 | * Make sure the interrupt happens and the character is received even | |
270 | * in the case the IRQ isn't wired, so that we can receive further | |
271 | * characters later. | |
272 | */ | |
273 | ||
274 | i8042_interrupt(0, NULL, NULL); | |
275 | return retval; | |
276 | } | |
277 | ||
1da177e4 LT |
278 | /* |
279 | * i8042_start() is called by serio core when port is about to finish | |
280 | * registering. It will mark port as existing so i8042_interrupt can | |
281 | * start sending data through it. | |
282 | */ | |
283 | static int i8042_start(struct serio *serio) | |
284 | { | |
285 | struct i8042_port *port = serio->port_data; | |
286 | ||
287 | port->exists = 1; | |
288 | mb(); | |
289 | return 0; | |
290 | } | |
291 | ||
292 | /* | |
293 | * i8042_stop() marks serio port as non-existing so i8042_interrupt | |
294 | * will not try to send data to the port that is about to go away. | |
295 | * The function is called by serio core as part of unregister procedure. | |
296 | */ | |
297 | static void i8042_stop(struct serio *serio) | |
298 | { | |
299 | struct i8042_port *port = serio->port_data; | |
300 | ||
301 | port->exists = 0; | |
b2b18660 | 302 | synchronize_sched(); |
1da177e4 LT |
303 | port->serio = NULL; |
304 | } | |
305 | ||
306 | /* | |
307 | * i8042_interrupt() is the most important function in this driver - | |
308 | * it handles the interrupts from the i8042, and sends incoming bytes | |
309 | * to the upper layers. | |
310 | */ | |
311 | ||
312 | static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |
313 | { | |
314 | struct i8042_port *port; | |
315 | unsigned long flags; | |
316 | unsigned char str, data; | |
317 | unsigned int dfl; | |
318 | unsigned int port_no; | |
319 | int ret; | |
320 | ||
1da177e4 LT |
321 | spin_lock_irqsave(&i8042_lock, flags); |
322 | str = i8042_read_status(); | |
323 | if (unlikely(~str & I8042_STR_OBF)) { | |
324 | spin_unlock_irqrestore(&i8042_lock, flags); | |
325 | if (irq) dbg("Interrupt %d, without any data", irq); | |
326 | ret = 0; | |
327 | goto out; | |
328 | } | |
329 | data = i8042_read_data(); | |
330 | spin_unlock_irqrestore(&i8042_lock, flags); | |
331 | ||
332 | if (i8042_mux_present && (str & I8042_STR_AUXDATA)) { | |
333 | static unsigned long last_transmit; | |
334 | static unsigned char last_str; | |
335 | ||
336 | dfl = 0; | |
337 | if (str & I8042_STR_MUXERR) { | |
338 | dbg("MUX error, status is %02x, data is %02x", str, data); | |
339 | switch (data) { | |
340 | default: | |
341 | /* | |
342 | * When MUXERR condition is signalled the data register can only contain | |
343 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | |
344 | * it is not always the case. Some KBC just get confused which port the | |
345 | * data came from and signal error leaving the data intact. They _do not_ | |
346 | * revert to legacy mode (actually I've never seen KBC reverting to legacy | |
347 | * mode yet, when we see one we'll add proper handling). | |
348 | * Anyway, we will assume that the data came from the same serio last byte | |
349 | * was transmitted (if transmission happened not too long ago). | |
350 | */ | |
351 | if (time_before(jiffies, last_transmit + HZ/10)) { | |
352 | str = last_str; | |
353 | break; | |
354 | } | |
355 | /* fall through - report timeout */ | |
356 | case 0xfd: | |
357 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; | |
358 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; | |
359 | } | |
360 | } | |
361 | ||
362 | port_no = I8042_MUX_PORT_NO + ((str >> 6) & 3); | |
363 | last_str = str; | |
364 | last_transmit = jiffies; | |
365 | } else { | |
366 | ||
367 | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | | |
368 | ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); | |
369 | ||
370 | port_no = (str & I8042_STR_AUXDATA) ? | |
371 | I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; | |
372 | } | |
373 | ||
374 | port = &i8042_ports[port_no]; | |
375 | ||
de9ce703 DT |
376 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", |
377 | data, port_no, irq, | |
1da177e4 LT |
378 | dfl & SERIO_PARITY ? ", bad parity" : "", |
379 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | |
380 | ||
381 | if (likely(port->exists)) | |
382 | serio_interrupt(port->serio, data, dfl, regs); | |
383 | ||
384 | ret = 1; | |
0854e52d | 385 | out: |
1da177e4 LT |
386 | return IRQ_RETVAL(ret); |
387 | } | |
388 | ||
de9ce703 DT |
389 | /* |
390 | * i8042_enable_kbd_port enables keybaord port on chip | |
391 | */ | |
392 | ||
393 | static int i8042_enable_kbd_port(void) | |
394 | { | |
395 | i8042_ctr &= ~I8042_CTR_KBDDIS; | |
396 | i8042_ctr |= I8042_CTR_KBDINT; | |
397 | ||
398 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | |
399 | printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n"); | |
400 | return -EIO; | |
401 | } | |
402 | ||
403 | return 0; | |
404 | } | |
405 | ||
406 | /* | |
407 | * i8042_enable_aux_port enables AUX (mouse) port on chip | |
408 | */ | |
409 | ||
410 | static int i8042_enable_aux_port(void) | |
411 | { | |
412 | i8042_ctr &= ~I8042_CTR_AUXDIS; | |
413 | i8042_ctr |= I8042_CTR_AUXINT; | |
414 | ||
415 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | |
416 | printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n"); | |
417 | return -EIO; | |
418 | } | |
419 | ||
420 | return 0; | |
421 | } | |
422 | ||
423 | /* | |
424 | * i8042_enable_mux_ports enables 4 individual AUX ports after | |
425 | * the controller has been switched into Multiplexed mode | |
426 | */ | |
427 | ||
428 | static int i8042_enable_mux_ports(void) | |
429 | { | |
430 | unsigned char param; | |
431 | int i; | |
432 | ||
433 | for (i = 0; i < I8042_NUM_MUX_PORTS; i++) { | |
434 | i8042_command(¶m, I8042_CMD_MUX_PFX + i); | |
435 | i8042_command(¶m, I8042_CMD_AUX_ENABLE); | |
436 | } | |
437 | ||
438 | return i8042_enable_aux_port(); | |
439 | } | |
440 | ||
1da177e4 LT |
441 | /* |
442 | * i8042_set_mux_mode checks whether the controller has an active | |
443 | * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode. | |
444 | */ | |
445 | ||
446 | static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) | |
447 | { | |
448 | ||
449 | unsigned char param; | |
450 | /* | |
451 | * Get rid of bytes in the queue. | |
452 | */ | |
453 | ||
454 | i8042_flush(); | |
455 | ||
456 | /* | |
457 | * Internal loopback test - send three bytes, they should come back from the | |
de9ce703 | 458 | * mouse interface, the last should be version. |
1da177e4 LT |
459 | */ |
460 | ||
461 | param = 0xf0; | |
463a4f76 | 462 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xf0) |
1da177e4 LT |
463 | return -1; |
464 | param = mode ? 0x56 : 0xf6; | |
463a4f76 | 465 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6)) |
1da177e4 LT |
466 | return -1; |
467 | param = mode ? 0xa4 : 0xa5; | |
463a4f76 | 468 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5)) |
1da177e4 LT |
469 | return -1; |
470 | ||
471 | if (mux_version) | |
463a4f76 | 472 | *mux_version = param; |
1da177e4 LT |
473 | |
474 | return 0; | |
475 | } | |
476 | ||
1da177e4 | 477 | /* |
de9ce703 DT |
478 | * i8042_check_mux() checks whether the controller supports the PS/2 Active |
479 | * Multiplexing specification by Synaptics, Phoenix, Insyde and | |
480 | * LCS/Telegraphics. | |
1da177e4 LT |
481 | */ |
482 | ||
de9ce703 | 483 | static int __devinit i8042_check_mux(void) |
1da177e4 | 484 | { |
de9ce703 DT |
485 | unsigned char mux_version; |
486 | ||
487 | if (i8042_set_mux_mode(1, &mux_version)) | |
488 | return -1; | |
489 | ||
1da177e4 | 490 | /* |
de9ce703 DT |
491 | * Workaround for interference with USB Legacy emulation |
492 | * that causes a v10.12 MUX to be found. | |
1da177e4 | 493 | */ |
de9ce703 DT |
494 | if (mux_version == 0xAC) |
495 | return -1; | |
496 | ||
497 | printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", | |
498 | (mux_version >> 4) & 0xf, mux_version & 0xf); | |
1da177e4 | 499 | |
de9ce703 DT |
500 | /* |
501 | * Disable all muxed ports by disabling AUX. | |
502 | */ | |
1da177e4 LT |
503 | i8042_ctr |= I8042_CTR_AUXDIS; |
504 | i8042_ctr &= ~I8042_CTR_AUXINT; | |
505 | ||
506 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | |
507 | printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n"); | |
de9ce703 | 508 | return -EIO; |
1da177e4 LT |
509 | } |
510 | ||
de9ce703 | 511 | i8042_mux_present = 1; |
1da177e4 LT |
512 | |
513 | return 0; | |
514 | } | |
515 | ||
1da177e4 | 516 | /* |
de9ce703 | 517 | * The following is used to test AUX IRQ delivery. |
1da177e4 | 518 | */ |
de9ce703 DT |
519 | static struct completion i8042_aux_irq_delivered __devinitdata; |
520 | static int i8042_irq_being_tested __devinitdata; | |
1da177e4 | 521 | |
de9ce703 | 522 | static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id, struct pt_regs *regs) |
1da177e4 | 523 | { |
de9ce703 DT |
524 | unsigned long flags; |
525 | unsigned char str, data; | |
1da177e4 | 526 | |
de9ce703 DT |
527 | spin_lock_irqsave(&i8042_lock, flags); |
528 | str = i8042_read_status(); | |
529 | if (str & I8042_STR_OBF) { | |
530 | data = i8042_read_data(); | |
531 | if (i8042_irq_being_tested && | |
532 | data == 0xa5 && (str & I8042_STR_AUXDATA)) | |
533 | complete(&i8042_aux_irq_delivered); | |
534 | } | |
535 | spin_unlock_irqrestore(&i8042_lock, flags); | |
1da177e4 | 536 | |
de9ce703 | 537 | return IRQ_HANDLED; |
1da177e4 LT |
538 | } |
539 | ||
540 | ||
541 | /* | |
542 | * i8042_check_aux() applies as much paranoia as it can at detecting | |
543 | * the presence of an AUX interface. | |
544 | */ | |
545 | ||
87fd6318 | 546 | static int __devinit i8042_check_aux(void) |
1da177e4 | 547 | { |
de9ce703 DT |
548 | int retval = -1; |
549 | int irq_registered = 0; | |
550 | unsigned long flags; | |
1da177e4 | 551 | unsigned char param; |
1da177e4 LT |
552 | |
553 | /* | |
554 | * Get rid of bytes in the queue. | |
555 | */ | |
556 | ||
557 | i8042_flush(); | |
558 | ||
559 | /* | |
560 | * Internal loopback test - filters out AT-type i8042's. Unfortunately | |
561 | * SiS screwed up and their 5597 doesn't support the LOOP command even | |
562 | * though it has an AUX port. | |
563 | */ | |
564 | ||
565 | param = 0x5a; | |
463a4f76 | 566 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x5a) { |
1da177e4 LT |
567 | |
568 | /* | |
569 | * External connection test - filters out AT-soldered PS/2 i8042's | |
570 | * 0x00 - no error, 0x01-0x03 - clock/data stuck, 0xff - general error | |
571 | * 0xfa - no error on some notebooks which ignore the spec | |
572 | * Because it's common for chipsets to return error on perfectly functioning | |
573 | * AUX ports, we test for this only when the LOOP command failed. | |
574 | */ | |
575 | ||
de9ce703 DT |
576 | if (i8042_command(¶m, I8042_CMD_AUX_TEST) || |
577 | (param && param != 0xfa && param != 0xff)) | |
578 | return -1; | |
1da177e4 LT |
579 | } |
580 | ||
581 | /* | |
582 | * Bit assignment test - filters out PS/2 i8042's in AT mode | |
583 | */ | |
584 | ||
585 | if (i8042_command(¶m, I8042_CMD_AUX_DISABLE)) | |
586 | return -1; | |
587 | if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) { | |
588 | printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); | |
589 | printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); | |
590 | } | |
591 | ||
592 | if (i8042_command(¶m, I8042_CMD_AUX_ENABLE)) | |
593 | return -1; | |
594 | if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS)) | |
595 | return -1; | |
596 | ||
597 | /* | |
de9ce703 DT |
598 | * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and |
599 | * used it for a PCI card or somethig else. | |
1da177e4 LT |
600 | */ |
601 | ||
de9ce703 DT |
602 | if (i8042_noloop) { |
603 | /* | |
604 | * Without LOOP command we can't test AUX IRQ delivery. Assume the port | |
605 | * is working and hope we are right. | |
606 | */ | |
607 | retval = 0; | |
608 | goto out; | |
609 | } | |
1da177e4 | 610 | |
de9ce703 DT |
611 | if (request_irq(I8042_AUX_IRQ, i8042_aux_test_irq, IRQF_SHARED, |
612 | "i8042", i8042_platform_device)) | |
613 | goto out; | |
1da177e4 | 614 | |
de9ce703 DT |
615 | irq_registered = 1; |
616 | ||
617 | if (i8042_enable_aux_port()) | |
618 | goto out; | |
619 | ||
620 | spin_lock_irqsave(&i8042_lock, flags); | |
1da177e4 | 621 | |
de9ce703 DT |
622 | init_completion(&i8042_aux_irq_delivered); |
623 | i8042_irq_being_tested = 1; | |
624 | ||
625 | param = 0xa5; | |
626 | retval = __i8042_command(¶m, I8042_CMD_AUX_LOOP & 0xf0ff); | |
627 | ||
628 | spin_unlock_irqrestore(&i8042_lock, flags); | |
629 | ||
630 | if (retval) | |
631 | goto out; | |
1da177e4 | 632 | |
de9ce703 DT |
633 | if (wait_for_completion_timeout(&i8042_aux_irq_delivered, |
634 | msecs_to_jiffies(250)) == 0) { | |
1da177e4 | 635 | /* |
de9ce703 DT |
636 | * AUX IRQ was never delivered so we need to flush the controller to |
637 | * get rid of the byte we put there; otherwise keyboard may not work. | |
1da177e4 | 638 | */ |
de9ce703 DT |
639 | i8042_flush(); |
640 | retval = -1; | |
641 | } | |
1da177e4 | 642 | |
de9ce703 | 643 | out: |
1da177e4 | 644 | |
de9ce703 DT |
645 | /* |
646 | * Disable the interface. | |
647 | */ | |
1da177e4 | 648 | |
de9ce703 DT |
649 | i8042_ctr |= I8042_CTR_AUXDIS; |
650 | i8042_ctr &= ~I8042_CTR_AUXINT; | |
1da177e4 | 651 | |
de9ce703 DT |
652 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) |
653 | retval = -1; | |
1da177e4 | 654 | |
de9ce703 DT |
655 | if (irq_registered) |
656 | free_irq(I8042_AUX_IRQ, i8042_platform_device); | |
1da177e4 | 657 | |
de9ce703 DT |
658 | return retval; |
659 | } | |
1da177e4 | 660 | |
de9ce703 | 661 | static int i8042_controller_check(void) |
1da177e4 | 662 | { |
de9ce703 DT |
663 | if (i8042_flush() == I8042_BUFFER_SIZE) { |
664 | printk(KERN_ERR "i8042.c: No controller found.\n"); | |
665 | return -ENODEV; | |
666 | } | |
667 | ||
668 | return 0; | |
1da177e4 LT |
669 | } |
670 | ||
de9ce703 | 671 | static int i8042_controller_selftest(void) |
2673c836 VP |
672 | { |
673 | unsigned char param; | |
674 | ||
675 | if (!i8042_reset) | |
676 | return 0; | |
677 | ||
678 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | |
679 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | |
de9ce703 | 680 | return -ENODEV; |
2673c836 VP |
681 | } |
682 | ||
683 | if (param != I8042_RET_CTL_TEST) { | |
684 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | |
685 | param, I8042_RET_CTL_TEST); | |
de9ce703 | 686 | return -EIO; |
2673c836 VP |
687 | } |
688 | ||
689 | return 0; | |
690 | } | |
1da177e4 LT |
691 | |
692 | /* | |
693 | * i8042_controller init initializes the i8042 controller, and, | |
694 | * most importantly, sets it into non-xlated mode if that's | |
695 | * desired. | |
696 | */ | |
697 | ||
698 | static int i8042_controller_init(void) | |
699 | { | |
700 | unsigned long flags; | |
701 | ||
1da177e4 LT |
702 | /* |
703 | * Save the CTR for restoral on unload / reboot. | |
704 | */ | |
705 | ||
706 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) { | |
707 | printk(KERN_ERR "i8042.c: Can't read CTR while initializing i8042.\n"); | |
de9ce703 | 708 | return -EIO; |
1da177e4 LT |
709 | } |
710 | ||
711 | i8042_initial_ctr = i8042_ctr; | |
712 | ||
713 | /* | |
714 | * Disable the keyboard interface and interrupt. | |
715 | */ | |
716 | ||
717 | i8042_ctr |= I8042_CTR_KBDDIS; | |
718 | i8042_ctr &= ~I8042_CTR_KBDINT; | |
719 | ||
720 | /* | |
721 | * Handle keylock. | |
722 | */ | |
723 | ||
724 | spin_lock_irqsave(&i8042_lock, flags); | |
725 | if (~i8042_read_status() & I8042_STR_KEYLOCK) { | |
726 | if (i8042_unlock) | |
727 | i8042_ctr |= I8042_CTR_IGNKEYLOCK; | |
728 | else | |
729 | printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); | |
730 | } | |
731 | spin_unlock_irqrestore(&i8042_lock, flags); | |
732 | ||
733 | /* | |
734 | * If the chip is configured into nontranslated mode by the BIOS, don't | |
735 | * bother enabling translating and be happy. | |
736 | */ | |
737 | ||
738 | if (~i8042_ctr & I8042_CTR_XLATE) | |
739 | i8042_direct = 1; | |
740 | ||
741 | /* | |
742 | * Set nontranslated mode for the kbd interface if requested by an option. | |
743 | * After this the kbd interface becomes a simple serial in/out, like the aux | |
744 | * interface is. We don't do this by default, since it can confuse notebook | |
745 | * BIOSes. | |
746 | */ | |
747 | ||
748 | if (i8042_direct) | |
749 | i8042_ctr &= ~I8042_CTR_XLATE; | |
750 | ||
751 | /* | |
752 | * Write CTR back. | |
753 | */ | |
754 | ||
755 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | |
756 | printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n"); | |
de9ce703 | 757 | return -EIO; |
1da177e4 LT |
758 | } |
759 | ||
760 | return 0; | |
761 | } | |
762 | ||
763 | ||
764 | /* | |
de9ce703 | 765 | * Reset the controller and reset CRT to the original value set by BIOS. |
1da177e4 | 766 | */ |
de9ce703 | 767 | |
1da177e4 LT |
768 | static void i8042_controller_reset(void) |
769 | { | |
de9ce703 | 770 | i8042_flush(); |
1da177e4 LT |
771 | |
772 | /* | |
773 | * Disable MUX mode if present. | |
774 | */ | |
775 | ||
776 | if (i8042_mux_present) | |
777 | i8042_set_mux_mode(0, NULL); | |
778 | ||
779 | /* | |
de9ce703 | 780 | * Reset the controller if requested. |
1da177e4 LT |
781 | */ |
782 | ||
de9ce703 | 783 | i8042_controller_selftest(); |
1da177e4 | 784 | |
de9ce703 DT |
785 | /* |
786 | * Restore the original control register setting. | |
787 | */ | |
788 | ||
789 | if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) | |
1da177e4 LT |
790 | printk(KERN_WARNING "i8042.c: Can't restore CTR.\n"); |
791 | } | |
792 | ||
793 | ||
794 | /* | |
795 | * Here we try to reset everything back to a state in which the BIOS will be | |
796 | * able to talk to the hardware when rebooting. | |
797 | */ | |
798 | ||
799 | static void i8042_controller_cleanup(void) | |
800 | { | |
801 | int i; | |
802 | ||
1da177e4 LT |
803 | /* |
804 | * Reset anything that is connected to the ports. | |
805 | */ | |
806 | ||
807 | for (i = 0; i < I8042_NUM_PORTS; i++) | |
de9ce703 | 808 | if (i8042_ports[i].serio) |
1da177e4 LT |
809 | serio_cleanup(i8042_ports[i].serio); |
810 | ||
811 | i8042_controller_reset(); | |
812 | } | |
813 | ||
814 | ||
815 | /* | |
816 | * i8042_panic_blink() will flash the keyboard LEDs and is called when | |
817 | * kernel panics. Flashing LEDs is useful for users running X who may | |
818 | * not see the console and will help distingushing panics from "real" | |
819 | * lockups. | |
820 | * | |
821 | * Note that DELAY has a limit of 10ms so we will not get stuck here | |
822 | * waiting for KBC to free up even if KBD interrupt is off | |
823 | */ | |
824 | ||
825 | #define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0) | |
826 | ||
827 | static long i8042_panic_blink(long count) | |
828 | { | |
829 | long delay = 0; | |
830 | static long last_blink; | |
831 | static char led; | |
832 | ||
833 | /* | |
834 | * We expect frequency to be about 1/2s. KDB uses about 1s. | |
835 | * Make sure they are different. | |
836 | */ | |
837 | if (!i8042_blink_frequency) | |
838 | return 0; | |
839 | if (count - last_blink < i8042_blink_frequency) | |
840 | return 0; | |
841 | ||
842 | led ^= 0x01 | 0x04; | |
843 | while (i8042_read_status() & I8042_STR_IBF) | |
844 | DELAY; | |
845 | i8042_write_data(0xed); /* set leds */ | |
846 | DELAY; | |
847 | while (i8042_read_status() & I8042_STR_IBF) | |
848 | DELAY; | |
849 | DELAY; | |
850 | i8042_write_data(led); | |
851 | DELAY; | |
852 | last_blink = count; | |
853 | return delay; | |
854 | } | |
855 | ||
856 | #undef DELAY | |
857 | ||
858 | /* | |
859 | * Here we try to restore the original BIOS settings | |
860 | */ | |
861 | ||
3ae5eaec | 862 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) |
1da177e4 | 863 | { |
de9ce703 | 864 | i8042_controller_cleanup(); |
1da177e4 LT |
865 | |
866 | return 0; | |
867 | } | |
868 | ||
869 | ||
870 | /* | |
871 | * Here we try to reset everything back to a state in which suspended | |
872 | */ | |
873 | ||
3ae5eaec | 874 | static int i8042_resume(struct platform_device *dev) |
1da177e4 | 875 | { |
de9ce703 | 876 | int error; |
1da177e4 | 877 | |
de9ce703 DT |
878 | error = i8042_controller_check(); |
879 | if (error) | |
880 | return error; | |
2673c836 | 881 | |
de9ce703 DT |
882 | error = i8042_controller_selftest(); |
883 | if (error) | |
884 | return error; | |
1da177e4 LT |
885 | |
886 | /* | |
de9ce703 | 887 | * Restore pre-resume CTR value and disable all ports |
1da177e4 LT |
888 | */ |
889 | ||
de9ce703 DT |
890 | i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; |
891 | i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); | |
892 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | |
893 | printk(KERN_ERR "i8042: Can't write CTR to resume\n"); | |
894 | return -EIO; | |
895 | } | |
1da177e4 | 896 | |
de9ce703 DT |
897 | if (i8042_mux_present) { |
898 | if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports()) | |
899 | printk(KERN_WARNING | |
900 | "i8042: failed to resume active multiplexor, " | |
901 | "mouse won't work.\n"); | |
902 | } else if (i8042_ports[I8042_AUX_PORT_NO].serio) | |
903 | i8042_enable_aux_port(); | |
1da177e4 | 904 | |
de9ce703 DT |
905 | if (i8042_ports[I8042_KBD_PORT_NO].serio) |
906 | i8042_enable_kbd_port(); | |
907 | ||
908 | i8042_interrupt(0, NULL, NULL); | |
1da177e4 LT |
909 | |
910 | return 0; | |
1da177e4 LT |
911 | } |
912 | ||
913 | /* | |
914 | * We need to reset the 8042 back to original mode on system shutdown, | |
915 | * because otherwise BIOSes will be confused. | |
916 | */ | |
917 | ||
3ae5eaec | 918 | static void i8042_shutdown(struct platform_device *dev) |
1da177e4 LT |
919 | { |
920 | i8042_controller_cleanup(); | |
921 | } | |
922 | ||
87fd6318 | 923 | static int __devinit i8042_create_kbd_port(void) |
1da177e4 LT |
924 | { |
925 | struct serio *serio; | |
926 | struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; | |
927 | ||
d39969de | 928 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
0854e52d DT |
929 | if (!serio) |
930 | return -ENOMEM; | |
931 | ||
932 | serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL; | |
933 | serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; | |
0854e52d DT |
934 | serio->start = i8042_start; |
935 | serio->stop = i8042_stop; | |
936 | serio->port_data = port; | |
937 | serio->dev.parent = &i8042_platform_device->dev; | |
de9ce703 | 938 | strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); |
0854e52d DT |
939 | strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); |
940 | ||
941 | port->serio = serio; | |
de9ce703 | 942 | port->irq = I8042_KBD_IRQ; |
0854e52d | 943 | |
de9ce703 | 944 | return 0; |
1da177e4 LT |
945 | } |
946 | ||
de9ce703 | 947 | static int __devinit i8042_create_aux_port(int idx) |
1da177e4 LT |
948 | { |
949 | struct serio *serio; | |
de9ce703 DT |
950 | int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; |
951 | struct i8042_port *port = &i8042_ports[port_no]; | |
1da177e4 | 952 | |
d39969de | 953 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
0854e52d DT |
954 | if (!serio) |
955 | return -ENOMEM; | |
956 | ||
957 | serio->id.type = SERIO_8042; | |
958 | serio->write = i8042_aux_write; | |
0854e52d DT |
959 | serio->start = i8042_start; |
960 | serio->stop = i8042_stop; | |
961 | serio->port_data = port; | |
962 | serio->dev.parent = &i8042_platform_device->dev; | |
de9ce703 DT |
963 | if (idx < 0) { |
964 | strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name)); | |
965 | strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); | |
966 | } else { | |
967 | snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx); | |
968 | snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1); | |
969 | } | |
0854e52d DT |
970 | |
971 | port->serio = serio; | |
de9ce703 DT |
972 | port->mux = idx; |
973 | port->irq = I8042_AUX_IRQ; | |
0854e52d | 974 | |
de9ce703 | 975 | return 0; |
1da177e4 LT |
976 | } |
977 | ||
de9ce703 | 978 | static void __devinit i8042_free_kbd_port(void) |
1da177e4 | 979 | { |
de9ce703 DT |
980 | kfree(i8042_ports[I8042_KBD_PORT_NO].serio); |
981 | i8042_ports[I8042_KBD_PORT_NO].serio = NULL; | |
982 | } | |
1da177e4 | 983 | |
de9ce703 DT |
984 | static void __devinit i8042_free_aux_ports(void) |
985 | { | |
986 | int i; | |
0854e52d | 987 | |
de9ce703 DT |
988 | for (i = I8042_AUX_PORT_NO; i < I8042_NUM_PORTS; i++) { |
989 | kfree(i8042_ports[i].serio); | |
990 | i8042_ports[i].serio = NULL; | |
991 | } | |
992 | } | |
0854e52d | 993 | |
de9ce703 DT |
994 | static void __devinit i8042_register_ports(void) |
995 | { | |
996 | int i; | |
0854e52d | 997 | |
de9ce703 DT |
998 | for (i = 0; i < I8042_NUM_PORTS; i++) { |
999 | if (i8042_ports[i].serio) { | |
1000 | printk(KERN_INFO "serio: %s at %#lx,%#lx irq %d\n", | |
1001 | i8042_ports[i].serio->name, | |
1002 | (unsigned long) I8042_DATA_REG, | |
1003 | (unsigned long) I8042_COMMAND_REG, | |
1004 | i8042_ports[i].irq); | |
1005 | serio_register_port(i8042_ports[i].serio); | |
1006 | } | |
1007 | } | |
1da177e4 LT |
1008 | } |
1009 | ||
de9ce703 | 1010 | static void __devinit i8042_unregister_ports(void) |
1da177e4 | 1011 | { |
de9ce703 | 1012 | int i; |
1da177e4 | 1013 | |
de9ce703 DT |
1014 | for (i = 0; i < I8042_NUM_PORTS; i++) { |
1015 | if (i8042_ports[i].serio) { | |
1016 | serio_unregister_port(i8042_ports[i].serio); | |
1017 | i8042_ports[i].serio = NULL; | |
1018 | } | |
1019 | } | |
1020 | } | |
1021 | ||
1022 | static void i8042_free_irqs(void) | |
1023 | { | |
1024 | if (i8042_aux_irq_registered) | |
1025 | free_irq(I8042_AUX_IRQ, i8042_platform_device); | |
1026 | if (i8042_kbd_irq_registered) | |
1027 | free_irq(I8042_KBD_IRQ, i8042_platform_device); | |
1028 | ||
1029 | i8042_aux_irq_registered = i8042_kbd_irq_registered = 0; | |
1030 | } | |
1031 | ||
1032 | static int __devinit i8042_setup_aux(void) | |
1033 | { | |
1034 | int (*aux_enable)(void); | |
1035 | int error; | |
1036 | int i; | |
1da177e4 | 1037 | |
de9ce703 | 1038 | if (i8042_check_aux()) |
87fd6318 | 1039 | return -ENODEV; |
1da177e4 | 1040 | |
de9ce703 DT |
1041 | if (i8042_nomux || i8042_check_mux()) { |
1042 | error = i8042_create_aux_port(-1); | |
1043 | if (error) | |
1044 | goto err_free_ports; | |
1045 | aux_enable = i8042_enable_aux_port; | |
1046 | } else { | |
1047 | for (i = 0; i < I8042_NUM_MUX_PORTS; i++) { | |
1048 | error = i8042_create_aux_port(i); | |
1049 | if (error) | |
1050 | goto err_free_ports; | |
0854e52d | 1051 | } |
de9ce703 | 1052 | aux_enable = i8042_enable_mux_ports; |
1da177e4 LT |
1053 | } |
1054 | ||
de9ce703 DT |
1055 | error = request_irq(I8042_AUX_IRQ, i8042_interrupt, IRQF_SHARED, |
1056 | "i8042", i8042_platform_device); | |
1057 | if (error) | |
1058 | goto err_free_ports; | |
945ef0d4 | 1059 | |
de9ce703 DT |
1060 | if (aux_enable()) |
1061 | goto err_free_irq; | |
1da177e4 | 1062 | |
de9ce703 | 1063 | i8042_aux_irq_registered = 1; |
1da177e4 | 1064 | return 0; |
0854e52d | 1065 | |
de9ce703 DT |
1066 | err_free_irq: |
1067 | free_irq(I8042_AUX_IRQ, i8042_platform_device); | |
1068 | err_free_ports: | |
1069 | i8042_free_aux_ports(); | |
1070 | return error; | |
1071 | } | |
0854e52d | 1072 | |
de9ce703 DT |
1073 | static int __devinit i8042_setup_kbd(void) |
1074 | { | |
1075 | int error; | |
1076 | ||
1077 | error = i8042_create_kbd_port(); | |
1078 | if (error) | |
1079 | return error; | |
1080 | ||
1081 | error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED, | |
1082 | "i8042", i8042_platform_device); | |
1083 | if (error) | |
1084 | goto err_free_port; | |
1085 | ||
1086 | error = i8042_enable_kbd_port(); | |
1087 | if (error) | |
1088 | goto err_free_irq; | |
1089 | ||
1090 | i8042_kbd_irq_registered = 1; | |
1091 | return 0; | |
1092 | ||
1093 | err_free_irq: | |
1094 | free_irq(I8042_KBD_IRQ, i8042_platform_device); | |
1095 | err_free_port: | |
1096 | i8042_free_kbd_port(); | |
1097 | return error; | |
1da177e4 LT |
1098 | } |
1099 | ||
de9ce703 | 1100 | static int __devinit i8042_probe(struct platform_device *dev) |
1da177e4 | 1101 | { |
de9ce703 | 1102 | int error; |
1da177e4 | 1103 | |
de9ce703 DT |
1104 | error = i8042_controller_selftest(); |
1105 | if (error) | |
1106 | return error; | |
1da177e4 | 1107 | |
de9ce703 DT |
1108 | error = i8042_controller_init(); |
1109 | if (error) | |
1110 | return error; | |
1111 | ||
1112 | if (!i8042_noaux) { | |
1113 | error = i8042_setup_aux(); | |
1114 | if (error && error != -ENODEV && error != -EBUSY) | |
1115 | goto out_fail; | |
1116 | } | |
1117 | ||
1118 | if (!i8042_nokbd) { | |
1119 | error = i8042_setup_kbd(); | |
1120 | if (error) | |
1121 | goto out_fail; | |
1122 | } | |
1da177e4 | 1123 | |
de9ce703 DT |
1124 | /* |
1125 | * Ok, everything is ready, let's register all serio ports | |
1126 | */ | |
1127 | i8042_register_ports(); | |
1128 | ||
1129 | return 0; | |
1130 | ||
1131 | out_fail: | |
1132 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ | |
1133 | i8042_free_irqs(); | |
1134 | i8042_controller_reset(); | |
1135 | ||
1136 | return error; | |
1137 | } | |
1138 | ||
1139 | static int __devexit i8042_remove(struct platform_device *dev) | |
1140 | { | |
1141 | i8042_unregister_ports(); | |
1142 | i8042_free_irqs(); | |
1143 | i8042_controller_reset(); | |
1da177e4 | 1144 | |
87fd6318 DT |
1145 | return 0; |
1146 | } | |
1147 | ||
1148 | static struct platform_driver i8042_driver = { | |
1149 | .driver = { | |
1150 | .name = "i8042", | |
1151 | .owner = THIS_MODULE, | |
1152 | }, | |
1153 | .probe = i8042_probe, | |
1154 | .remove = __devexit_p(i8042_remove), | |
1155 | .suspend = i8042_suspend, | |
1156 | .resume = i8042_resume, | |
1157 | .shutdown = i8042_shutdown, | |
1158 | }; | |
1159 | ||
1160 | static int __init i8042_init(void) | |
1161 | { | |
1162 | int err; | |
1163 | ||
1164 | dbg_init(); | |
1165 | ||
1166 | err = i8042_platform_init(); | |
1167 | if (err) | |
1168 | return err; | |
1169 | ||
de9ce703 DT |
1170 | err = i8042_controller_check(); |
1171 | if (err) | |
1172 | goto err_platform_exit; | |
87fd6318 DT |
1173 | |
1174 | err = platform_driver_register(&i8042_driver); | |
1175 | if (err) | |
1176 | goto err_platform_exit; | |
1177 | ||
1178 | i8042_platform_device = platform_device_alloc("i8042", -1); | |
1179 | if (!i8042_platform_device) { | |
1180 | err = -ENOMEM; | |
1181 | goto err_unregister_driver; | |
1182 | } | |
1183 | ||
1184 | err = platform_device_add(i8042_platform_device); | |
1185 | if (err) | |
1186 | goto err_free_device; | |
1187 | ||
de9ce703 DT |
1188 | panic_blink = i8042_panic_blink; |
1189 | ||
87fd6318 DT |
1190 | return 0; |
1191 | ||
1192 | err_free_device: | |
1193 | platform_device_put(i8042_platform_device); | |
1194 | err_unregister_driver: | |
1195 | platform_driver_unregister(&i8042_driver); | |
1196 | err_platform_exit: | |
1197 | i8042_platform_exit(); | |
1198 | ||
1199 | return err; | |
1200 | } | |
1201 | ||
1202 | static void __exit i8042_exit(void) | |
1203 | { | |
1da177e4 | 1204 | platform_device_unregister(i8042_platform_device); |
3ae5eaec | 1205 | platform_driver_unregister(&i8042_driver); |
1da177e4 LT |
1206 | i8042_platform_exit(); |
1207 | ||
1208 | panic_blink = NULL; | |
1209 | } | |
1210 | ||
1211 | module_init(i8042_init); | |
1212 | module_exit(i8042_exit); |