Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.9-rc2 1245 lines 29 kB view raw
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 31static int i8042_kbd_irq; 32static 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 42static int i8042_command_reg = 0x64; 43static int i8042_data_reg = 0x60; 44 45 46static inline int i8042_read_data(void) 47{ 48 return inb(I8042_DATA_REG); 49} 50 51static inline int i8042_read_status(void) 52{ 53 return inb(I8042_STATUS_REG); 54} 55 56static inline void i8042_write_data(int val) 57{ 58 outb(val, I8042_DATA_REG); 59} 60 61static inline void i8042_write_command(int val) 62{ 63 outb(val, I8042_COMMAND_REG); 64} 65 66#ifdef CONFIG_X86 67 68#include <linux/dmi.h> 69 70static 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 */ 233static 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 /* Lenovo XiaoXin Air 12 */ 430 .matches = { 431 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 432 DMI_MATCH(DMI_PRODUCT_NAME, "80UN"), 433 }, 434 }, 435 { 436 .matches = { 437 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 438 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), 439 }, 440 }, 441 { 442 /* Acer Aspire 5710 */ 443 .matches = { 444 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 445 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), 446 }, 447 }, 448 { 449 /* Acer Aspire 7738 */ 450 .matches = { 451 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 452 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), 453 }, 454 }, 455 { 456 /* Gericom Bellagio */ 457 .matches = { 458 DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), 459 DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), 460 }, 461 }, 462 { 463 /* IBM 2656 */ 464 .matches = { 465 DMI_MATCH(DMI_SYS_VENDOR, "IBM"), 466 DMI_MATCH(DMI_PRODUCT_NAME, "2656"), 467 }, 468 }, 469 { 470 /* Dell XPS M1530 */ 471 .matches = { 472 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 473 DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), 474 }, 475 }, 476 { 477 /* Compal HEL80I */ 478 .matches = { 479 DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), 480 DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), 481 }, 482 }, 483 { 484 /* Dell Vostro 1510 */ 485 .matches = { 486 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 487 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), 488 }, 489 }, 490 { 491 /* Acer Aspire 5536 */ 492 .matches = { 493 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 494 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), 495 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), 496 }, 497 }, 498 { 499 /* Dell Vostro V13 */ 500 .matches = { 501 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 502 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), 503 }, 504 }, 505 { 506 /* Newer HP Pavilion dv4 models */ 507 .matches = { 508 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 509 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), 510 }, 511 }, 512 { 513 /* Asus X450LCP */ 514 .matches = { 515 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 516 DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), 517 }, 518 }, 519 { 520 /* Avatar AVIU-145A6 */ 521 .matches = { 522 DMI_MATCH(DMI_SYS_VENDOR, "Intel"), 523 DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), 524 }, 525 }, 526 { 527 /* TUXEDO BU1406 */ 528 .matches = { 529 DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 530 DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), 531 }, 532 }, 533 { 534 /* Lenovo LaVie Z */ 535 .matches = { 536 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 537 DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), 538 }, 539 }, 540 { 541 /* 542 * Acer Aspire 5738z 543 * Touchpad stops working in mux mode when dis- + re-enabled 544 * with the touchpad enable/disable toggle hotkey 545 */ 546 .matches = { 547 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 548 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), 549 }, 550 }, 551 { } 552}; 553 554static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = { 555 { 556 /* 557 * Sony Vaio VGN-CS series require MUX or the touch sensor 558 * buttons will disturb touchpad operation 559 */ 560 .matches = { 561 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 562 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), 563 }, 564 }, 565 { } 566}; 567 568/* 569 * On some Asus laptops, just running self tests cause problems. 570 */ 571static const struct dmi_system_id i8042_dmi_noselftest_table[] = { 572 { 573 .matches = { 574 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 575 DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ 576 }, 577 }, 578 { } 579}; 580static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { 581 { 582 /* MSI Wind U-100 */ 583 .matches = { 584 DMI_MATCH(DMI_BOARD_NAME, "U-100"), 585 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), 586 }, 587 }, 588 { 589 /* LG Electronics X110 */ 590 .matches = { 591 DMI_MATCH(DMI_BOARD_NAME, "X110"), 592 DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), 593 }, 594 }, 595 { 596 /* Acer Aspire One 150 */ 597 .matches = { 598 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 599 DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), 600 }, 601 }, 602 { 603 /* Advent 4211 */ 604 .matches = { 605 DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), 606 DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), 607 }, 608 }, 609 { 610 /* Medion Akoya Mini E1210 */ 611 .matches = { 612 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 613 DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), 614 }, 615 }, 616 { 617 /* Medion Akoya E1222 */ 618 .matches = { 619 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 620 DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), 621 }, 622 }, 623 { 624 /* Mivvy M310 */ 625 .matches = { 626 DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), 627 DMI_MATCH(DMI_PRODUCT_NAME, "N10"), 628 }, 629 }, 630 { 631 /* Dell Vostro 1320 */ 632 .matches = { 633 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 634 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), 635 }, 636 }, 637 { 638 /* Dell Vostro 1520 */ 639 .matches = { 640 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 641 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), 642 }, 643 }, 644 { 645 /* Dell Vostro 1720 */ 646 .matches = { 647 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 648 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), 649 }, 650 }, 651 { 652 /* Lenovo Ideapad U455 */ 653 .matches = { 654 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 655 DMI_MATCH(DMI_PRODUCT_NAME, "20046"), 656 }, 657 }, 658 { 659 /* Lenovo ThinkPad L460 */ 660 .matches = { 661 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 662 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), 663 }, 664 }, 665 { 666 /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ 667 .matches = { 668 DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 669 DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), 670 }, 671 }, 672 { 673 /* Lenovo ThinkPad Twist S230u */ 674 .matches = { 675 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 676 DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), 677 }, 678 }, 679 { } 680}; 681 682#ifdef CONFIG_PNP 683static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { 684 { 685 /* Intel MBO Desktop D845PESV */ 686 .matches = { 687 DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), 688 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 689 }, 690 }, 691 { 692 /* 693 * Intel NUC D54250WYK - does not have i8042 controller but 694 * declares PS/2 devices in DSDT. 695 */ 696 .matches = { 697 DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), 698 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 699 }, 700 }, 701 { 702 /* MSI Wind U-100 */ 703 .matches = { 704 DMI_MATCH(DMI_BOARD_NAME, "U-100"), 705 DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), 706 }, 707 }, 708 { } 709}; 710 711static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { 712 { 713 .matches = { 714 DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ 715 }, 716 }, 717 { 718 .matches = { 719 DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ 720 }, 721 }, 722 { 723 .matches = { 724 DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ 725 }, 726 }, 727 { 728 .matches = { 729 DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ 730 }, 731 }, 732 { } 733}; 734#endif 735 736static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { 737 { 738 /* Dell Vostro V13 */ 739 .matches = { 740 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 741 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), 742 }, 743 }, 744 { 745 /* Newer HP Pavilion dv4 models */ 746 .matches = { 747 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 748 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), 749 }, 750 }, 751 { 752 /* Fujitsu A544 laptop */ 753 /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ 754 .matches = { 755 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 756 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), 757 }, 758 }, 759 { 760 /* Fujitsu AH544 laptop */ 761 /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ 762 .matches = { 763 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 764 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), 765 }, 766 }, 767 { 768 /* Fujitsu U574 laptop */ 769 /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ 770 .matches = { 771 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 772 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), 773 }, 774 }, 775 { 776 /* Fujitsu UH554 laptop */ 777 .matches = { 778 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), 779 DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), 780 }, 781 }, 782 { } 783}; 784 785/* 786 * Some Wistron based laptops need us to explicitly enable the 'Dritek 787 * keyboard extension' to make their extra keys start generating scancodes. 788 * Originally, this was just confined to older laptops, but a few Acer laptops 789 * have turned up in 2007 that also need this again. 790 */ 791static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { 792 { 793 /* Acer Aspire 5100 */ 794 .matches = { 795 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 796 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), 797 }, 798 }, 799 { 800 /* Acer Aspire 5610 */ 801 .matches = { 802 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 803 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 804 }, 805 }, 806 { 807 /* Acer Aspire 5630 */ 808 .matches = { 809 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 810 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 811 }, 812 }, 813 { 814 /* Acer Aspire 5650 */ 815 .matches = { 816 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 817 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 818 }, 819 }, 820 { 821 /* Acer Aspire 5680 */ 822 .matches = { 823 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 824 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 825 }, 826 }, 827 { 828 /* Acer Aspire 5720 */ 829 .matches = { 830 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 831 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), 832 }, 833 }, 834 { 835 /* Acer Aspire 9110 */ 836 .matches = { 837 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 838 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 839 }, 840 }, 841 { 842 /* Acer TravelMate 660 */ 843 .matches = { 844 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 845 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), 846 }, 847 }, 848 { 849 /* Acer TravelMate 2490 */ 850 .matches = { 851 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 852 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 853 }, 854 }, 855 { 856 /* Acer TravelMate 4280 */ 857 .matches = { 858 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 859 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), 860 }, 861 }, 862 { } 863}; 864 865/* 866 * Some laptops need keyboard reset before probing for the trackpad to get 867 * it detected, initialised & finally work. 868 */ 869static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { 870 { 871 /* Gigabyte P35 v2 - Elantech touchpad */ 872 .matches = { 873 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), 874 DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), 875 }, 876 }, 877 { 878 /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ 879 .matches = { 880 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), 881 DMI_MATCH(DMI_PRODUCT_NAME, "X3"), 882 }, 883 }, 884 { 885 /* Gigabyte P34 - Elantech touchpad */ 886 .matches = { 887 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), 888 DMI_MATCH(DMI_PRODUCT_NAME, "P34"), 889 }, 890 }, 891 { 892 /* Gigabyte P57 - Elantech touchpad */ 893 .matches = { 894 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), 895 DMI_MATCH(DMI_PRODUCT_NAME, "P57"), 896 }, 897 }, 898 { 899 /* Schenker XMG C504 - Elantech touchpad */ 900 .matches = { 901 DMI_MATCH(DMI_SYS_VENDOR, "XMG"), 902 DMI_MATCH(DMI_PRODUCT_NAME, "C504"), 903 }, 904 }, 905 { } 906}; 907 908#endif /* CONFIG_X86 */ 909 910#ifdef CONFIG_PNP 911#include <linux/pnp.h> 912 913static bool i8042_pnp_kbd_registered; 914static unsigned int i8042_pnp_kbd_devices; 915static bool i8042_pnp_aux_registered; 916static unsigned int i8042_pnp_aux_devices; 917 918static int i8042_pnp_command_reg; 919static int i8042_pnp_data_reg; 920static int i8042_pnp_kbd_irq; 921static int i8042_pnp_aux_irq; 922 923static char i8042_pnp_kbd_name[32]; 924static char i8042_pnp_aux_name[32]; 925 926static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) 927{ 928 strlcpy(dst, "PNP:", dst_size); 929 930 while (id) { 931 strlcat(dst, " ", dst_size); 932 strlcat(dst, id->id, dst_size); 933 id = id->next; 934 } 935} 936 937static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 938{ 939 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 940 i8042_pnp_data_reg = pnp_port_start(dev,0); 941 942 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 943 i8042_pnp_command_reg = pnp_port_start(dev, 1); 944 945 if (pnp_irq_valid(dev,0)) 946 i8042_pnp_kbd_irq = pnp_irq(dev, 0); 947 948 strlcpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name)); 949 if (strlen(pnp_dev_name(dev))) { 950 strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); 951 strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); 952 } 953 i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id, 954 sizeof(i8042_kbd_firmware_id)); 955 i8042_kbd_fwnode = dev_fwnode(&dev->dev); 956 957 /* Keyboard ports are always supposed to be wakeup-enabled */ 958 device_set_wakeup_enable(&dev->dev, true); 959 960 i8042_pnp_kbd_devices++; 961 return 0; 962} 963 964static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did) 965{ 966 if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) 967 i8042_pnp_data_reg = pnp_port_start(dev,0); 968 969 if (pnp_port_valid(dev, 1) && pnp_port_len(dev, 1) == 1) 970 i8042_pnp_command_reg = pnp_port_start(dev, 1); 971 972 if (pnp_irq_valid(dev, 0)) 973 i8042_pnp_aux_irq = pnp_irq(dev, 0); 974 975 strlcpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name)); 976 if (strlen(pnp_dev_name(dev))) { 977 strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); 978 strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); 979 } 980 i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id, 981 sizeof(i8042_aux_firmware_id)); 982 983 i8042_pnp_aux_devices++; 984 return 0; 985} 986 987static const struct pnp_device_id pnp_kbd_devids[] = { 988 { .id = "PNP0300", .driver_data = 0 }, 989 { .id = "PNP0301", .driver_data = 0 }, 990 { .id = "PNP0302", .driver_data = 0 }, 991 { .id = "PNP0303", .driver_data = 0 }, 992 { .id = "PNP0304", .driver_data = 0 }, 993 { .id = "PNP0305", .driver_data = 0 }, 994 { .id = "PNP0306", .driver_data = 0 }, 995 { .id = "PNP0309", .driver_data = 0 }, 996 { .id = "PNP030a", .driver_data = 0 }, 997 { .id = "PNP030b", .driver_data = 0 }, 998 { .id = "PNP0320", .driver_data = 0 }, 999 { .id = "PNP0343", .driver_data = 0 }, 1000 { .id = "PNP0344", .driver_data = 0 }, 1001 { .id = "PNP0345", .driver_data = 0 }, 1002 { .id = "CPQA0D7", .driver_data = 0 }, 1003 { .id = "", }, 1004}; 1005MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); 1006 1007static struct pnp_driver i8042_pnp_kbd_driver = { 1008 .name = "i8042 kbd", 1009 .id_table = pnp_kbd_devids, 1010 .probe = i8042_pnp_kbd_probe, 1011 .driver = { 1012 .probe_type = PROBE_FORCE_SYNCHRONOUS, 1013 .suppress_bind_attrs = true, 1014 }, 1015}; 1016 1017static const struct pnp_device_id pnp_aux_devids[] = { 1018 { .id = "AUI0200", .driver_data = 0 }, 1019 { .id = "FJC6000", .driver_data = 0 }, 1020 { .id = "FJC6001", .driver_data = 0 }, 1021 { .id = "PNP0f03", .driver_data = 0 }, 1022 { .id = "PNP0f0b", .driver_data = 0 }, 1023 { .id = "PNP0f0e", .driver_data = 0 }, 1024 { .id = "PNP0f12", .driver_data = 0 }, 1025 { .id = "PNP0f13", .driver_data = 0 }, 1026 { .id = "PNP0f19", .driver_data = 0 }, 1027 { .id = "PNP0f1c", .driver_data = 0 }, 1028 { .id = "SYN0801", .driver_data = 0 }, 1029 { .id = "", }, 1030}; 1031MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); 1032 1033static struct pnp_driver i8042_pnp_aux_driver = { 1034 .name = "i8042 aux", 1035 .id_table = pnp_aux_devids, 1036 .probe = i8042_pnp_aux_probe, 1037 .driver = { 1038 .probe_type = PROBE_FORCE_SYNCHRONOUS, 1039 .suppress_bind_attrs = true, 1040 }, 1041}; 1042 1043static void i8042_pnp_exit(void) 1044{ 1045 if (i8042_pnp_kbd_registered) { 1046 i8042_pnp_kbd_registered = false; 1047 pnp_unregister_driver(&i8042_pnp_kbd_driver); 1048 } 1049 1050 if (i8042_pnp_aux_registered) { 1051 i8042_pnp_aux_registered = false; 1052 pnp_unregister_driver(&i8042_pnp_aux_driver); 1053 } 1054} 1055 1056static int __init i8042_pnp_init(void) 1057{ 1058 char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; 1059 bool pnp_data_busted = false; 1060 int err; 1061 1062#ifdef CONFIG_X86 1063 if (dmi_check_system(i8042_dmi_nopnp_table)) 1064 i8042_nopnp = true; 1065#endif 1066 1067 if (i8042_nopnp) { 1068 pr_info("PNP detection disabled\n"); 1069 return 0; 1070 } 1071 1072 err = pnp_register_driver(&i8042_pnp_kbd_driver); 1073 if (!err) 1074 i8042_pnp_kbd_registered = true; 1075 1076 err = pnp_register_driver(&i8042_pnp_aux_driver); 1077 if (!err) 1078 i8042_pnp_aux_registered = true; 1079 1080 if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { 1081 i8042_pnp_exit(); 1082#if defined(__ia64__) 1083 return -ENODEV; 1084#else 1085 pr_info("PNP: No PS/2 controller found.\n"); 1086 if (x86_platform.legacy.i8042 != 1087 X86_LEGACY_I8042_EXPECTED_PRESENT) 1088 return -ENODEV; 1089 pr_info("Probing ports directly.\n"); 1090 return 0; 1091#endif 1092 } 1093 1094 if (i8042_pnp_kbd_devices) 1095 snprintf(kbd_irq_str, sizeof(kbd_irq_str), 1096 "%d", i8042_pnp_kbd_irq); 1097 if (i8042_pnp_aux_devices) 1098 snprintf(aux_irq_str, sizeof(aux_irq_str), 1099 "%d", i8042_pnp_aux_irq); 1100 1101 pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", 1102 i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 1103 i8042_pnp_aux_name, 1104 i8042_pnp_data_reg, i8042_pnp_command_reg, 1105 kbd_irq_str, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", 1106 aux_irq_str); 1107 1108#if defined(__ia64__) 1109 if (!i8042_pnp_kbd_devices) 1110 i8042_nokbd = true; 1111 if (!i8042_pnp_aux_devices) 1112 i8042_noaux = true; 1113#endif 1114 1115 if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && 1116 i8042_pnp_data_reg != i8042_data_reg) || 1117 !i8042_pnp_data_reg) { 1118 pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", 1119 i8042_pnp_data_reg, i8042_data_reg); 1120 i8042_pnp_data_reg = i8042_data_reg; 1121 pnp_data_busted = true; 1122 } 1123 1124 if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && 1125 i8042_pnp_command_reg != i8042_command_reg) || 1126 !i8042_pnp_command_reg) { 1127 pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", 1128 i8042_pnp_command_reg, i8042_command_reg); 1129 i8042_pnp_command_reg = i8042_command_reg; 1130 pnp_data_busted = true; 1131 } 1132 1133 if (!i8042_nokbd && !i8042_pnp_kbd_irq) { 1134 pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", 1135 i8042_kbd_irq); 1136 i8042_pnp_kbd_irq = i8042_kbd_irq; 1137 pnp_data_busted = true; 1138 } 1139 1140 if (!i8042_noaux && !i8042_pnp_aux_irq) { 1141 if (!pnp_data_busted && i8042_pnp_kbd_irq) { 1142 pr_warn("PNP: PS/2 appears to have AUX port disabled, " 1143 "if this is incorrect please boot with i8042.nopnp\n"); 1144 i8042_noaux = true; 1145 } else { 1146 pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", 1147 i8042_aux_irq); 1148 i8042_pnp_aux_irq = i8042_aux_irq; 1149 } 1150 } 1151 1152 i8042_data_reg = i8042_pnp_data_reg; 1153 i8042_command_reg = i8042_pnp_command_reg; 1154 i8042_kbd_irq = i8042_pnp_kbd_irq; 1155 i8042_aux_irq = i8042_pnp_aux_irq; 1156 1157#ifdef CONFIG_X86 1158 i8042_bypass_aux_irq_test = !pnp_data_busted && 1159 dmi_check_system(i8042_dmi_laptop_table); 1160#endif 1161 1162 return 0; 1163} 1164 1165#else /* !CONFIG_PNP */ 1166static inline int i8042_pnp_init(void) { return 0; } 1167static inline void i8042_pnp_exit(void) { } 1168#endif /* CONFIG_PNP */ 1169 1170static int __init i8042_platform_init(void) 1171{ 1172 int retval; 1173 1174#ifdef CONFIG_X86 1175 u8 a20_on = 0xdf; 1176 /* Just return if platform does not have i8042 controller */ 1177 if (x86_platform.legacy.i8042 == X86_LEGACY_I8042_PLATFORM_ABSENT) 1178 return -ENODEV; 1179#endif 1180 1181/* 1182 * On ix86 platforms touching the i8042 data register region can do really 1183 * bad things. Because of this the region is always reserved on ix86 boxes. 1184 * 1185 * if (!request_region(I8042_DATA_REG, 16, "i8042")) 1186 * return -EBUSY; 1187 */ 1188 1189 i8042_kbd_irq = I8042_MAP_IRQ(1); 1190 i8042_aux_irq = I8042_MAP_IRQ(12); 1191 1192 retval = i8042_pnp_init(); 1193 if (retval) 1194 return retval; 1195 1196#if defined(__ia64__) 1197 i8042_reset = I8042_RESET_ALWAYS; 1198#endif 1199 1200#ifdef CONFIG_X86 1201 /* Honor module parameter when value is not default */ 1202 if (i8042_reset == I8042_RESET_DEFAULT) { 1203 if (dmi_check_system(i8042_dmi_reset_table)) 1204 i8042_reset = I8042_RESET_ALWAYS; 1205 1206 if (dmi_check_system(i8042_dmi_noselftest_table)) 1207 i8042_reset = I8042_RESET_NEVER; 1208 } 1209 1210 if (dmi_check_system(i8042_dmi_noloop_table)) 1211 i8042_noloop = true; 1212 1213 if (dmi_check_system(i8042_dmi_nomux_table)) 1214 i8042_nomux = true; 1215 1216 if (dmi_check_system(i8042_dmi_forcemux_table)) 1217 i8042_nomux = false; 1218 1219 if (dmi_check_system(i8042_dmi_notimeout_table)) 1220 i8042_notimeout = true; 1221 1222 if (dmi_check_system(i8042_dmi_dritek_table)) 1223 i8042_dritek = true; 1224 1225 if (dmi_check_system(i8042_dmi_kbdreset_table)) 1226 i8042_kbdreset = true; 1227 1228 /* 1229 * A20 was already enabled during early kernel init. But some buggy 1230 * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to 1231 * resume from S3. So we do it here and hope that nothing breaks. 1232 */ 1233 i8042_command(&a20_on, 0x10d1); 1234 i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ 1235#endif /* CONFIG_X86 */ 1236 1237 return retval; 1238} 1239 1240static inline void i8042_platform_exit(void) 1241{ 1242 i8042_pnp_exit(); 1243} 1244 1245#endif /* _I8042_X86IA64IO_H */