Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-only */
2 : : #ifndef _I8042_X86IA64IO_H
3 : : #define _I8042_X86IA64IO_H
4 : :
5 : :
6 : : #ifdef CONFIG_X86
7 : : #include <asm/x86_init.h>
8 : : #endif
9 : :
10 : : /*
11 : : * Names.
12 : : */
13 : :
14 : : #define I8042_KBD_PHYS_DESC "isa0060/serio0"
15 : : #define I8042_AUX_PHYS_DESC "isa0060/serio1"
16 : : #define I8042_MUX_PHYS_DESC "isa0060/serio%d"
17 : :
18 : : /*
19 : : * IRQs.
20 : : */
21 : :
22 : : #if defined(__ia64__)
23 : : # define I8042_MAP_IRQ(x) isa_irq_to_vector((x))
24 : : #else
25 : : # define I8042_MAP_IRQ(x) (x)
26 : : #endif
27 : :
28 : : #define I8042_KBD_IRQ i8042_kbd_irq
29 : : #define I8042_AUX_IRQ i8042_aux_irq
30 : :
31 : : static int i8042_kbd_irq;
32 : : static int i8042_aux_irq;
33 : :
34 : : /*
35 : : * Register numbers.
36 : : */
37 : :
38 : : #define I8042_COMMAND_REG i8042_command_reg
39 : : #define I8042_STATUS_REG i8042_command_reg
40 : : #define I8042_DATA_REG i8042_data_reg
41 : :
42 : : static int i8042_command_reg = 0x64;
43 : : static int i8042_data_reg = 0x60;
44 : :
45 : :
46 : 3976 : static inline int i8042_read_data(void)
47 : : {
48 [ - + - + : 3976 : return inb(I8042_DATA_REG);
- + - - ]
49 : : }
50 : :
51 : 11032 : static inline int i8042_read_status(void)
52 : : {
53 [ + + ]: 11032 : return inb(I8042_STATUS_REG);
54 : : }
55 : :
56 : 3388 : static inline void i8042_write_data(int val)
57 : : {
58 : 3388 : outb(val, I8042_DATA_REG);
59 : 196 : }
60 : :
61 : 3388 : static inline void i8042_write_command(int val)
62 : : {
63 : 3388 : outb(val, I8042_COMMAND_REG);
64 : : }
65 : :
66 : : #ifdef CONFIG_X86
67 : :
68 : : #include <linux/dmi.h>
69 : :
70 : : static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
71 : : {
72 : : /*
73 : : * Arima-Rioworks HDAMB -
74 : : * AUX LOOP command does not raise AUX IRQ
75 : : */
76 : : .matches = {
77 : : DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"),
78 : : DMI_MATCH(DMI_BOARD_NAME, "HDAMB"),
79 : : DMI_MATCH(DMI_BOARD_VERSION, "Rev E"),
80 : : },
81 : : },
82 : : {
83 : : /* ASUS G1S */
84 : : .matches = {
85 : : DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
86 : : DMI_MATCH(DMI_BOARD_NAME, "G1S"),
87 : : DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
88 : : },
89 : : },
90 : : {
91 : : /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */
92 : : .matches = {
93 : : DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
94 : : DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"),
95 : : DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"),
96 : : },
97 : : },
98 : : {
99 : : .matches = {
100 : : DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
101 : : DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"),
102 : : },
103 : : },
104 : : {
105 : : .matches = {
106 : : DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
107 : : DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
108 : : DMI_MATCH(DMI_PRODUCT_VERSION, "8500"),
109 : : },
110 : : },
111 : : {
112 : : .matches = {
113 : : DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
114 : : DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"),
115 : : DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
116 : : },
117 : : },
118 : : {
119 : : /* Dell Embedded Box PC 3000 */
120 : : .matches = {
121 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
122 : : DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
123 : : },
124 : : },
125 : : {
126 : : /* OQO Model 01 */
127 : : .matches = {
128 : : DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
129 : : DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
130 : : DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
131 : : },
132 : : },
133 : : {
134 : : /* ULI EV4873 - AUX LOOP does not work properly */
135 : : .matches = {
136 : : DMI_MATCH(DMI_SYS_VENDOR, "ULI"),
137 : : DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"),
138 : : DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
139 : : },
140 : : },
141 : : {
142 : : /* Microsoft Virtual Machine */
143 : : .matches = {
144 : : DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
145 : : DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
146 : : DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
147 : : },
148 : : },
149 : : {
150 : : /* Medion MAM 2070 */
151 : : .matches = {
152 : : DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
153 : : DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"),
154 : : DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
155 : : },
156 : : },
157 : : {
158 : : /* Medion Akoya E7225 */
159 : : .matches = {
160 : : DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
161 : : DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"),
162 : : DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
163 : : },
164 : : },
165 : : {
166 : : /* Blue FB5601 */
167 : : .matches = {
168 : : DMI_MATCH(DMI_SYS_VENDOR, "blue"),
169 : : DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"),
170 : : DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
171 : : },
172 : : },
173 : : {
174 : : /* Gigabyte M912 */
175 : : .matches = {
176 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
177 : : DMI_MATCH(DMI_PRODUCT_NAME, "M912"),
178 : : DMI_MATCH(DMI_PRODUCT_VERSION, "01"),
179 : : },
180 : : },
181 : : {
182 : : /* Gigabyte M1022M netbook */
183 : : .matches = {
184 : : DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."),
185 : : DMI_MATCH(DMI_BOARD_NAME, "M1022E"),
186 : : DMI_MATCH(DMI_BOARD_VERSION, "1.02"),
187 : : },
188 : : },
189 : : {
190 : : /* Gigabyte Spring Peak - defines wrong chassis type */
191 : : .matches = {
192 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
193 : : DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"),
194 : : },
195 : : },
196 : : {
197 : : /* Gigabyte T1005 - defines wrong chassis type ("Other") */
198 : : .matches = {
199 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
200 : : DMI_MATCH(DMI_PRODUCT_NAME, "T1005"),
201 : : },
202 : : },
203 : : {
204 : : /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */
205 : : .matches = {
206 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
207 : : DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"),
208 : : },
209 : : },
210 : : {
211 : : .matches = {
212 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
213 : : DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"),
214 : : DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
215 : : },
216 : : },
217 : : {
218 : : .matches = {
219 : : DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
220 : : DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
221 : : },
222 : : },
223 : : { }
224 : : };
225 : :
226 : : /*
227 : : * Some Fujitsu notebooks are having trouble with touchpads if
228 : : * active multiplexing mode is activated. Luckily they don't have
229 : : * external PS/2 ports so we can safely disable it.
230 : : * ... apparently some Toshibas don't like MUX mode either and
231 : : * die horrible death on reboot.
232 : : */
233 : : static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
234 : : {
235 : : /* Fujitsu Lifebook P7010/P7010D */
236 : : .matches = {
237 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
238 : : DMI_MATCH(DMI_PRODUCT_NAME, "P7010"),
239 : : },
240 : : },
241 : : {
242 : : /* Fujitsu Lifebook P7010 */
243 : : .matches = {
244 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
245 : : DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"),
246 : : },
247 : : },
248 : : {
249 : : /* Fujitsu Lifebook P5020D */
250 : : .matches = {
251 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
252 : : DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"),
253 : : },
254 : : },
255 : : {
256 : : /* Fujitsu Lifebook S2000 */
257 : : .matches = {
258 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
259 : : DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"),
260 : : },
261 : : },
262 : : {
263 : : /* Fujitsu Lifebook S6230 */
264 : : .matches = {
265 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
266 : : DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"),
267 : : },
268 : : },
269 : : {
270 : : /* Fujitsu Lifebook U745 */
271 : : .matches = {
272 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
273 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"),
274 : : },
275 : : },
276 : : {
277 : : /* Fujitsu T70H */
278 : : .matches = {
279 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
280 : : DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"),
281 : : },
282 : : },
283 : : {
284 : : /* Fujitsu-Siemens Lifebook T3010 */
285 : : .matches = {
286 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
287 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
288 : : },
289 : : },
290 : : {
291 : : /* Fujitsu-Siemens Lifebook E4010 */
292 : : .matches = {
293 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
294 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"),
295 : : },
296 : : },
297 : : {
298 : : /* Fujitsu-Siemens Amilo Pro 2010 */
299 : : .matches = {
300 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
301 : : DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"),
302 : : },
303 : : },
304 : : {
305 : : /* Fujitsu-Siemens Amilo Pro 2030 */
306 : : .matches = {
307 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
308 : : DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"),
309 : : },
310 : : },
311 : : {
312 : : /*
313 : : * No data is coming from the touchscreen unless KBC
314 : : * is in legacy mode.
315 : : */
316 : : /* Panasonic CF-29 */
317 : : .matches = {
318 : : DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
319 : : DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
320 : : },
321 : : },
322 : : {
323 : : /*
324 : : * HP Pavilion DV4017EA -
325 : : * errors on MUX ports are reported without raising AUXDATA
326 : : * causing "spurious NAK" messages.
327 : : */
328 : : .matches = {
329 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
330 : : DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"),
331 : : },
332 : : },
333 : : {
334 : : /*
335 : : * HP Pavilion ZT1000 -
336 : : * like DV4017EA does not raise AUXERR for errors on MUX ports.
337 : : */
338 : : .matches = {
339 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
340 : : DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
341 : : DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
342 : : },
343 : : },
344 : : {
345 : : /*
346 : : * HP Pavilion DV4270ca -
347 : : * like DV4017EA does not raise AUXERR for errors on MUX ports.
348 : : */
349 : : .matches = {
350 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
351 : : DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"),
352 : : },
353 : : },
354 : : {
355 : : .matches = {
356 : : DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
357 : : DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
358 : : },
359 : : },
360 : : {
361 : : .matches = {
362 : : DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
363 : : DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
364 : : },
365 : : },
366 : : {
367 : : .matches = {
368 : : DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
369 : : DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
370 : : },
371 : : },
372 : : {
373 : : .matches = {
374 : : DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
375 : : DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
376 : : },
377 : : },
378 : : {
379 : : /* Sharp Actius MM20 */
380 : : .matches = {
381 : : DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
382 : : DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
383 : : },
384 : : },
385 : : {
386 : : /* Sony Vaio FS-115b */
387 : : .matches = {
388 : : DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
389 : : DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"),
390 : : },
391 : : },
392 : : {
393 : : /*
394 : : * Sony Vaio FZ-240E -
395 : : * reset and GET ID commands issued via KBD port are
396 : : * sometimes being delivered to AUX3.
397 : : */
398 : : .matches = {
399 : : DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
400 : : DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
401 : : },
402 : : },
403 : : {
404 : : /*
405 : : * Most (all?) VAIOs do not have external PS/2 ports nor
406 : : * they implement active multiplexing properly, and
407 : : * MUX discovery usually messes up keyboard/touchpad.
408 : : */
409 : : .matches = {
410 : : DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
411 : : DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
412 : : },
413 : : },
414 : : {
415 : : /* Amoi M636/A737 */
416 : : .matches = {
417 : : DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."),
418 : : DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
419 : : },
420 : : },
421 : : {
422 : : /* Lenovo 3000 n100 */
423 : : .matches = {
424 : : DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
425 : : DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
426 : : },
427 : : },
428 : : {
429 : : .matches = {
430 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
431 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
432 : : },
433 : : },
434 : : {
435 : : /* Acer Aspire 5710 */
436 : : .matches = {
437 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
438 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"),
439 : : },
440 : : },
441 : : {
442 : : /* Acer Aspire 7738 */
443 : : .matches = {
444 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
445 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"),
446 : : },
447 : : },
448 : : {
449 : : /* Gericom Bellagio */
450 : : .matches = {
451 : : DMI_MATCH(DMI_SYS_VENDOR, "Gericom"),
452 : : DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
453 : : },
454 : : },
455 : : {
456 : : /* IBM 2656 */
457 : : .matches = {
458 : : DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
459 : : DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
460 : : },
461 : : },
462 : : {
463 : : /* Dell XPS M1530 */
464 : : .matches = {
465 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
466 : : DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
467 : : },
468 : : },
469 : : {
470 : : /* Compal HEL80I */
471 : : .matches = {
472 : : DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
473 : : DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
474 : : },
475 : : },
476 : : {
477 : : /* Dell Vostro 1510 */
478 : : .matches = {
479 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
480 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
481 : : },
482 : : },
483 : : {
484 : : /* Acer Aspire 5536 */
485 : : .matches = {
486 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
487 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
488 : : DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
489 : : },
490 : : },
491 : : {
492 : : /* Dell Vostro V13 */
493 : : .matches = {
494 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
495 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
496 : : },
497 : : },
498 : : {
499 : : /* Newer HP Pavilion dv4 models */
500 : : .matches = {
501 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
502 : : DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
503 : : },
504 : : },
505 : : {
506 : : /* Asus X450LCP */
507 : : .matches = {
508 : : DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
509 : : DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
510 : : },
511 : : },
512 : : {
513 : : /* Avatar AVIU-145A6 */
514 : : .matches = {
515 : : DMI_MATCH(DMI_SYS_VENDOR, "Intel"),
516 : : DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
517 : : },
518 : : },
519 : : {
520 : : /* TUXEDO BU1406 */
521 : : .matches = {
522 : : DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
523 : : DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
524 : : },
525 : : },
526 : : {
527 : : /* Lenovo LaVie Z */
528 : : .matches = {
529 : : DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
530 : : DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"),
531 : : },
532 : : },
533 : : { }
534 : : };
535 : :
536 : : static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = {
537 : : {
538 : : /*
539 : : * Sony Vaio VGN-CS series require MUX or the touch sensor
540 : : * buttons will disturb touchpad operation
541 : : */
542 : : .matches = {
543 : : DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
544 : : DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"),
545 : : },
546 : : },
547 : : { }
548 : : };
549 : :
550 : : /*
551 : : * On some Asus laptops, just running self tests cause problems.
552 : : */
553 : : static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
554 : : {
555 : : .matches = {
556 : : DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
557 : : DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
558 : : },
559 : : },
560 : : { }
561 : : };
562 : : static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
563 : : {
564 : : /* MSI Wind U-100 */
565 : : .matches = {
566 : : DMI_MATCH(DMI_BOARD_NAME, "U-100"),
567 : : DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
568 : : },
569 : : },
570 : : {
571 : : /* LG Electronics X110 */
572 : : .matches = {
573 : : DMI_MATCH(DMI_BOARD_NAME, "X110"),
574 : : DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
575 : : },
576 : : },
577 : : {
578 : : /* Acer Aspire One 150 */
579 : : .matches = {
580 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
581 : : DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
582 : : },
583 : : },
584 : : {
585 : : /* Advent 4211 */
586 : : .matches = {
587 : : DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"),
588 : : DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"),
589 : : },
590 : : },
591 : : {
592 : : /* Medion Akoya Mini E1210 */
593 : : .matches = {
594 : : DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
595 : : DMI_MATCH(DMI_PRODUCT_NAME, "E1210"),
596 : : },
597 : : },
598 : : {
599 : : /* Medion Akoya E1222 */
600 : : .matches = {
601 : : DMI_MATCH(DMI_SYS_VENDOR, "MEDION"),
602 : : DMI_MATCH(DMI_PRODUCT_NAME, "E122X"),
603 : : },
604 : : },
605 : : {
606 : : /* Mivvy M310 */
607 : : .matches = {
608 : : DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"),
609 : : DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
610 : : },
611 : : },
612 : : {
613 : : /* Dell Vostro 1320 */
614 : : .matches = {
615 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
616 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
617 : : },
618 : : },
619 : : {
620 : : /* Dell Vostro 1520 */
621 : : .matches = {
622 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
623 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
624 : : },
625 : : },
626 : : {
627 : : /* Dell Vostro 1720 */
628 : : .matches = {
629 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
630 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
631 : : },
632 : : },
633 : : {
634 : : /* Lenovo Ideapad U455 */
635 : : .matches = {
636 : : DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
637 : : DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
638 : : },
639 : : },
640 : : {
641 : : /* Lenovo ThinkPad L460 */
642 : : .matches = {
643 : : DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
644 : : DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"),
645 : : },
646 : : },
647 : : {
648 : : /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
649 : : .matches = {
650 : : DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
651 : : DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
652 : : },
653 : : },
654 : : { }
655 : : };
656 : :
657 : : #ifdef CONFIG_PNP
658 : : static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = {
659 : : {
660 : : /* Intel MBO Desktop D845PESV */
661 : : .matches = {
662 : : DMI_MATCH(DMI_BOARD_NAME, "D845PESV"),
663 : : DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
664 : : },
665 : : },
666 : : {
667 : : /*
668 : : * Intel NUC D54250WYK - does not have i8042 controller but
669 : : * declares PS/2 devices in DSDT.
670 : : */
671 : : .matches = {
672 : : DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"),
673 : : DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
674 : : },
675 : : },
676 : : {
677 : : /* MSI Wind U-100 */
678 : : .matches = {
679 : : DMI_MATCH(DMI_BOARD_NAME, "U-100"),
680 : : DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
681 : : },
682 : : },
683 : : { }
684 : : };
685 : :
686 : : static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
687 : : {
688 : : .matches = {
689 : : DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
690 : : },
691 : : },
692 : : {
693 : : .matches = {
694 : : DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
695 : : },
696 : : },
697 : : {
698 : : .matches = {
699 : : DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
700 : : },
701 : : },
702 : : {
703 : : .matches = {
704 : : DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
705 : : },
706 : : },
707 : : { }
708 : : };
709 : : #endif
710 : :
711 : : static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
712 : : {
713 : : /* Dell Vostro V13 */
714 : : .matches = {
715 : : DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
716 : : DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
717 : : },
718 : : },
719 : : {
720 : : /* Newer HP Pavilion dv4 models */
721 : : .matches = {
722 : : DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
723 : : DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"),
724 : : },
725 : : },
726 : : {
727 : : /* Fujitsu A544 laptop */
728 : : /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
729 : : .matches = {
730 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
731 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
732 : : },
733 : : },
734 : : {
735 : : /* Fujitsu AH544 laptop */
736 : : /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
737 : : .matches = {
738 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
739 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
740 : : },
741 : : },
742 : : {
743 : : /* Fujitsu U574 laptop */
744 : : /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
745 : : .matches = {
746 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
747 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
748 : : },
749 : : },
750 : : {
751 : : /* Fujitsu UH554 laptop */
752 : : .matches = {
753 : : DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
754 : : DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
755 : : },
756 : : },
757 : : { }
758 : : };
759 : :
760 : : /*
761 : : * Some Wistron based laptops need us to explicitly enable the 'Dritek
762 : : * keyboard extension' to make their extra keys start generating scancodes.
763 : : * Originally, this was just confined to older laptops, but a few Acer laptops
764 : : * have turned up in 2007 that also need this again.
765 : : */
766 : : static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = {
767 : : {
768 : : /* Acer Aspire 5100 */
769 : : .matches = {
770 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
771 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
772 : : },
773 : : },
774 : : {
775 : : /* Acer Aspire 5610 */
776 : : .matches = {
777 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
778 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
779 : : },
780 : : },
781 : : {
782 : : /* Acer Aspire 5630 */
783 : : .matches = {
784 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
785 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"),
786 : : },
787 : : },
788 : : {
789 : : /* Acer Aspire 5650 */
790 : : .matches = {
791 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
792 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"),
793 : : },
794 : : },
795 : : {
796 : : /* Acer Aspire 5680 */
797 : : .matches = {
798 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
799 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"),
800 : : },
801 : : },
802 : : {
803 : : /* Acer Aspire 5720 */
804 : : .matches = {
805 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
806 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
807 : : },
808 : : },
809 : : {
810 : : /* Acer Aspire 9110 */
811 : : .matches = {
812 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
813 : : DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"),
814 : : },
815 : : },
816 : : {
817 : : /* Acer TravelMate 660 */
818 : : .matches = {
819 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
820 : : DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"),
821 : : },
822 : : },
823 : : {
824 : : /* Acer TravelMate 2490 */
825 : : .matches = {
826 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
827 : : DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"),
828 : : },
829 : : },
830 : : {
831 : : /* Acer TravelMate 4280 */
832 : : .matches = {
833 : : DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
834 : : DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
835 : : },
836 : : },
837 : : { }
838 : : };
839 : :
840 : : /*
841 : : * Some laptops need keyboard reset before probing for the trackpad to get
842 : : * it detected, initialised & finally work.
843 : : */
844 : : static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
845 : : {
846 : : /* Gigabyte P35 v2 - Elantech touchpad */
847 : : .matches = {
848 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
849 : : DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"),
850 : : },
851 : : },
852 : : {
853 : : /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */
854 : : .matches = {
855 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
856 : : DMI_MATCH(DMI_PRODUCT_NAME, "X3"),
857 : : },
858 : : },
859 : : {
860 : : /* Gigabyte P34 - Elantech touchpad */
861 : : .matches = {
862 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
863 : : DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
864 : : },
865 : : },
866 : : {
867 : : /* Gigabyte P57 - Elantech touchpad */
868 : : .matches = {
869 : : DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
870 : : DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
871 : : },
872 : : },
873 : : {
874 : : /* Schenker XMG C504 - Elantech touchpad */
875 : : .matches = {
876 : : DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
877 : : DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
878 : : },
879 : : },
880 : : { }
881 : : };
882 : :
883 : : #endif /* CONFIG_X86 */
884 : :
885 : : #ifdef CONFIG_PNP
886 : : #include <linux/pnp.h>
887 : :
888 : : static bool i8042_pnp_kbd_registered;
889 : : static unsigned int i8042_pnp_kbd_devices;
890 : : static bool i8042_pnp_aux_registered;
891 : : static unsigned int i8042_pnp_aux_devices;
892 : :
893 : : static int i8042_pnp_command_reg;
894 : : static int i8042_pnp_data_reg;
895 : : static int i8042_pnp_kbd_irq;
896 : : static int i8042_pnp_aux_irq;
897 : :
898 : : static char i8042_pnp_kbd_name[32];
899 : : static char i8042_pnp_aux_name[32];
900 : :
901 : 56 : static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
902 : : {
903 : 56 : strlcpy(dst, "PNP:", dst_size);
904 : :
905 [ + + ]: 112 : while (id) {
906 : 56 : strlcat(dst, " ", dst_size);
907 : 56 : strlcat(dst, id->id, dst_size);
908 : 56 : id = id->next;
909 : : }
910 : 56 : }
911 : :
912 : 28 : static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
913 : : {
914 [ + - ]: 56 : if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
915 : 56 : i8042_pnp_data_reg = pnp_port_start(dev,0);
916 : :
917 [ + - ]: 56 : if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
918 : 56 : i8042_pnp_command_reg = pnp_port_start(dev, 1);
919 : :
920 : 28 : if (pnp_irq_valid(dev,0))
921 : 56 : i8042_pnp_kbd_irq = pnp_irq(dev, 0);
922 : :
923 : 28 : strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
924 [ + - ]: 28 : if (strlen(pnp_dev_name(dev))) {
925 : 28 : strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
926 : 28 : strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
927 : : }
928 : 28 : i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
929 : : sizeof(i8042_kbd_firmware_id));
930 : :
931 : : /* Keyboard ports are always supposed to be wakeup-enabled */
932 : 28 : device_set_wakeup_enable(&dev->dev, true);
933 : :
934 : 28 : i8042_pnp_kbd_devices++;
935 : 28 : return 0;
936 : : }
937 : :
938 : 28 : static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
939 : : {
940 [ - - ]: 28 : if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
941 : 0 : i8042_pnp_data_reg = pnp_port_start(dev,0);
942 : :
943 [ - - ]: 28 : if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1)
944 : 0 : i8042_pnp_command_reg = pnp_port_start(dev, 1);
945 : :
946 : 28 : if (pnp_irq_valid(dev, 0))
947 : 56 : i8042_pnp_aux_irq = pnp_irq(dev, 0);
948 : :
949 : 28 : strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
950 [ + - ]: 28 : if (strlen(pnp_dev_name(dev))) {
951 : 28 : strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
952 : 28 : strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
953 : : }
954 : 28 : i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
955 : : sizeof(i8042_aux_firmware_id));
956 : :
957 : 28 : i8042_pnp_aux_devices++;
958 : 28 : return 0;
959 : : }
960 : :
961 : : static const struct pnp_device_id pnp_kbd_devids[] = {
962 : : { .id = "PNP0300", .driver_data = 0 },
963 : : { .id = "PNP0301", .driver_data = 0 },
964 : : { .id = "PNP0302", .driver_data = 0 },
965 : : { .id = "PNP0303", .driver_data = 0 },
966 : : { .id = "PNP0304", .driver_data = 0 },
967 : : { .id = "PNP0305", .driver_data = 0 },
968 : : { .id = "PNP0306", .driver_data = 0 },
969 : : { .id = "PNP0309", .driver_data = 0 },
970 : : { .id = "PNP030a", .driver_data = 0 },
971 : : { .id = "PNP030b", .driver_data = 0 },
972 : : { .id = "PNP0320", .driver_data = 0 },
973 : : { .id = "PNP0343", .driver_data = 0 },
974 : : { .id = "PNP0344", .driver_data = 0 },
975 : : { .id = "PNP0345", .driver_data = 0 },
976 : : { .id = "CPQA0D7", .driver_data = 0 },
977 : : { .id = "", },
978 : : };
979 : : MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids);
980 : :
981 : : static struct pnp_driver i8042_pnp_kbd_driver = {
982 : : .name = "i8042 kbd",
983 : : .id_table = pnp_kbd_devids,
984 : : .probe = i8042_pnp_kbd_probe,
985 : : .driver = {
986 : : .probe_type = PROBE_FORCE_SYNCHRONOUS,
987 : : .suppress_bind_attrs = true,
988 : : },
989 : : };
990 : :
991 : : static const struct pnp_device_id pnp_aux_devids[] = {
992 : : { .id = "AUI0200", .driver_data = 0 },
993 : : { .id = "FJC6000", .driver_data = 0 },
994 : : { .id = "FJC6001", .driver_data = 0 },
995 : : { .id = "PNP0f03", .driver_data = 0 },
996 : : { .id = "PNP0f0b", .driver_data = 0 },
997 : : { .id = "PNP0f0e", .driver_data = 0 },
998 : : { .id = "PNP0f12", .driver_data = 0 },
999 : : { .id = "PNP0f13", .driver_data = 0 },
1000 : : { .id = "PNP0f19", .driver_data = 0 },
1001 : : { .id = "PNP0f1c", .driver_data = 0 },
1002 : : { .id = "SYN0801", .driver_data = 0 },
1003 : : { .id = "", },
1004 : : };
1005 : : MODULE_DEVICE_TABLE(pnp, pnp_aux_devids);
1006 : :
1007 : : static struct pnp_driver i8042_pnp_aux_driver = {
1008 : : .name = "i8042 aux",
1009 : : .id_table = pnp_aux_devids,
1010 : : .probe = i8042_pnp_aux_probe,
1011 : : .driver = {
1012 : : .probe_type = PROBE_FORCE_SYNCHRONOUS,
1013 : : .suppress_bind_attrs = true,
1014 : : },
1015 : : };
1016 : :
1017 : 0 : static void i8042_pnp_exit(void)
1018 : : {
1019 [ # # ]: 0 : if (i8042_pnp_kbd_registered) {
1020 : 0 : i8042_pnp_kbd_registered = false;
1021 : 0 : pnp_unregister_driver(&i8042_pnp_kbd_driver);
1022 : : }
1023 : :
1024 [ # # ]: 0 : if (i8042_pnp_aux_registered) {
1025 : 0 : i8042_pnp_aux_registered = false;
1026 : 0 : pnp_unregister_driver(&i8042_pnp_aux_driver);
1027 : : }
1028 : 0 : }
1029 : :
1030 : 28 : static int __init i8042_pnp_init(void)
1031 : : {
1032 : 28 : char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
1033 : 28 : bool pnp_data_busted = false;
1034 : 28 : int err;
1035 : :
1036 : : #ifdef CONFIG_X86
1037 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_nopnp_table))
1038 : 0 : i8042_nopnp = true;
1039 : : #endif
1040 : :
1041 [ - + ]: 28 : if (i8042_nopnp) {
1042 : 0 : pr_info("PNP detection disabled\n");
1043 : 0 : return 0;
1044 : : }
1045 : :
1046 : 28 : err = pnp_register_driver(&i8042_pnp_kbd_driver);
1047 [ + - ]: 28 : if (!err)
1048 : 28 : i8042_pnp_kbd_registered = true;
1049 : :
1050 : 28 : err = pnp_register_driver(&i8042_pnp_aux_driver);
1051 [ + - ]: 28 : if (!err)
1052 : 28 : i8042_pnp_aux_registered = true;
1053 : :
1054 [ - + - - ]: 28 : if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
1055 : 0 : i8042_pnp_exit();
1056 : : #if defined(__ia64__)
1057 : : return -ENODEV;
1058 : : #else
1059 : 0 : pr_info("PNP: No PS/2 controller found.\n");
1060 [ # # ]: 0 : if (x86_platform.legacy.i8042 !=
1061 : : X86_LEGACY_I8042_EXPECTED_PRESENT)
1062 : : return -ENODEV;
1063 : 0 : pr_info("Probing ports directly.\n");
1064 : 0 : return 0;
1065 : : #endif
1066 : : }
1067 : :
1068 [ + - ]: 28 : if (i8042_pnp_kbd_devices)
1069 : 28 : snprintf(kbd_irq_str, sizeof(kbd_irq_str),
1070 : : "%d", i8042_pnp_kbd_irq);
1071 [ + - ]: 28 : if (i8042_pnp_aux_devices)
1072 : 28 : snprintf(aux_irq_str, sizeof(aux_irq_str),
1073 : : "%d", i8042_pnp_aux_irq);
1074 : :
1075 [ + - - + : 28 : pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n",
+ - - + ]
1076 : : i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
1077 : : i8042_pnp_aux_name,
1078 : : i8042_pnp_data_reg, i8042_pnp_command_reg,
1079 : : kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "",
1080 : : aux_irq_str);
1081 : :
1082 : : #if defined(__ia64__)
1083 : : if (!i8042_pnp_kbd_devices)
1084 : : i8042_nokbd = true;
1085 : : if (!i8042_pnp_aux_devices)
1086 : : i8042_noaux = true;
1087 : : #endif
1088 : :
1089 [ + - + - ]: 28 : if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
1090 [ - + ]: 28 : i8042_pnp_data_reg != i8042_data_reg) ||
1091 : : !i8042_pnp_data_reg) {
1092 : 0 : pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n",
1093 : : i8042_pnp_data_reg, i8042_data_reg);
1094 : 0 : i8042_pnp_data_reg = i8042_data_reg;
1095 : 0 : pnp_data_busted = true;
1096 : : }
1097 : :
1098 [ + - + - ]: 28 : if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
1099 [ - + ]: 28 : i8042_pnp_command_reg != i8042_command_reg) ||
1100 : : !i8042_pnp_command_reg) {
1101 : 0 : pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n",
1102 : : i8042_pnp_command_reg, i8042_command_reg);
1103 : 0 : i8042_pnp_command_reg = i8042_command_reg;
1104 : 0 : pnp_data_busted = true;
1105 : : }
1106 : :
1107 [ + - - + ]: 28 : if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
1108 : 0 : pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n",
1109 : : i8042_kbd_irq);
1110 : 0 : i8042_pnp_kbd_irq = i8042_kbd_irq;
1111 : 0 : pnp_data_busted = true;
1112 : : }
1113 : :
1114 [ + - - + ]: 28 : if (!i8042_noaux && !i8042_pnp_aux_irq) {
1115 [ # # # # ]: 0 : if (!pnp_data_busted && i8042_pnp_kbd_irq) {
1116 : 0 : pr_warn("PNP: PS/2 appears to have AUX port disabled, "
1117 : : "if this is incorrect please boot with i8042.nopnp\n");
1118 : 0 : i8042_noaux = true;
1119 : : } else {
1120 : 0 : pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n",
1121 : : i8042_aux_irq);
1122 : 0 : i8042_pnp_aux_irq = i8042_aux_irq;
1123 : : }
1124 : : }
1125 : :
1126 : 28 : i8042_data_reg = i8042_pnp_data_reg;
1127 : 28 : i8042_command_reg = i8042_pnp_command_reg;
1128 : 28 : i8042_kbd_irq = i8042_pnp_kbd_irq;
1129 : 28 : i8042_aux_irq = i8042_pnp_aux_irq;
1130 : :
1131 : : #ifdef CONFIG_X86
1132 [ + - + - ]: 56 : i8042_bypass_aux_irq_test = !pnp_data_busted &&
1133 : 28 : dmi_check_system(i8042_dmi_laptop_table);
1134 : : #endif
1135 : :
1136 : 28 : return 0;
1137 : : }
1138 : :
1139 : : #else /* !CONFIG_PNP */
1140 : : static inline int i8042_pnp_init(void) { return 0; }
1141 : : static inline void i8042_pnp_exit(void) { }
1142 : : #endif /* CONFIG_PNP */
1143 : :
1144 : 28 : static int __init i8042_platform_init(void)
1145 : : {
1146 : 28 : int retval;
1147 : :
1148 : : #ifdef CONFIG_X86
1149 : 28 : u8 a20_on = 0xdf;
1150 : : /* Just return if platform does not have i8042 controller */
1151 [ + - ]: 28 : if (x86_platform.legacy.i8042 == X86_LEGACY_I8042_PLATFORM_ABSENT)
1152 : : return -ENODEV;
1153 : : #endif
1154 : :
1155 : : /*
1156 : : * On ix86 platforms touching the i8042 data register region can do really
1157 : : * bad things. Because of this the region is always reserved on ix86 boxes.
1158 : : *
1159 : : * if (!request_region(I8042_DATA_REG, 16, "i8042"))
1160 : : * return -EBUSY;
1161 : : */
1162 : :
1163 : 28 : i8042_kbd_irq = I8042_MAP_IRQ(1);
1164 : 28 : i8042_aux_irq = I8042_MAP_IRQ(12);
1165 : :
1166 : 28 : retval = i8042_pnp_init();
1167 [ + - ]: 28 : if (retval)
1168 : : return retval;
1169 : :
1170 : : #if defined(__ia64__)
1171 : : i8042_reset = I8042_RESET_ALWAYS;
1172 : : #endif
1173 : :
1174 : : #ifdef CONFIG_X86
1175 : : /* Honor module parameter when value is not default */
1176 [ + - ]: 28 : if (i8042_reset == I8042_RESET_DEFAULT) {
1177 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_reset_table))
1178 : 0 : i8042_reset = I8042_RESET_ALWAYS;
1179 : :
1180 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_noselftest_table))
1181 : 0 : i8042_reset = I8042_RESET_NEVER;
1182 : : }
1183 : :
1184 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_noloop_table))
1185 : 0 : i8042_noloop = true;
1186 : :
1187 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_nomux_table))
1188 : 0 : i8042_nomux = true;
1189 : :
1190 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_forcemux_table))
1191 : 0 : i8042_nomux = false;
1192 : :
1193 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_notimeout_table))
1194 : 0 : i8042_notimeout = true;
1195 : :
1196 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_dritek_table))
1197 : 0 : i8042_dritek = true;
1198 : :
1199 [ - + ]: 28 : if (dmi_check_system(i8042_dmi_kbdreset_table))
1200 : 0 : i8042_kbdreset = true;
1201 : :
1202 : : /*
1203 : : * A20 was already enabled during early kernel init. But some buggy
1204 : : * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to
1205 : : * resume from S3. So we do it here and hope that nothing breaks.
1206 : : */
1207 : 28 : i8042_command(&a20_on, 0x10d1);
1208 : 28 : i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */
1209 : : #endif /* CONFIG_X86 */
1210 : :
1211 : 28 : return retval;
1212 : : }
1213 : :
1214 : 0 : static inline void i8042_platform_exit(void)
1215 : : {
1216 : 0 : i8042_pnp_exit();
1217 : : }
1218 : :
1219 : : #endif /* _I8042_X86IA64IO_H */
|