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

Input: i8042 - add deferred probe support

We've got a bug report about the non-working keyboard on ASUS ZenBook
UX425UA. It seems that the PS/2 device isn't ready immediately at
boot but takes some seconds to get ready. Until now, the only
workaround is to defer the probe, but it's available only when the
driver is a module. However, many distros, including openSUSE as in
the original report, build the PS/2 input drivers into kernel, hence
it won't work easily.

This patch adds the support for the deferred probe for i8042 stuff as
a workaround of the problem above. When the deferred probe mode is
enabled and the device couldn't be probed, it'll be repeated with the
standard deferred probe mechanism.

The deferred probe mode is enabled either via the new option
i8042.probe_defer or via the quirk table entry. As of this patch, the
quirk table contains only ASUS ZenBook UX425UA.

The deferred probe part is based on Fabio's initial work.

BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1190256
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Samuel Čavoj <samuel@cavoj.net>
Link: https://lore.kernel.org/r/20211117063757.11380-1-tiwai@suse.de

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Takashi Iwai and committed by
Dmitry Torokhov
9222ba68 efe6f16c

+51 -19
+2
Documentation/admin-guide/kernel-parameters.txt
··· 1627 1627 architectures force reset to be always executed 1628 1628 i8042.unlock [HW] Unlock (ignore) the keylock 1629 1629 i8042.kbdreset [HW] Reset device connected to KBD port 1630 + i8042.probe_defer 1631 + [HW] Allow deferred probing upon i8042 probe errors 1630 1632 1631 1633 i810= [HW,DRM] 1632 1634
+14
drivers/input/serio/i8042-x86ia64io.h
··· 995 995 { } 996 996 }; 997 997 998 + static const struct dmi_system_id i8042_dmi_probe_defer_table[] __initconst = { 999 + { 1000 + /* ASUS ZenBook UX425UA */ 1001 + .matches = { 1002 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1003 + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"), 1004 + }, 1005 + }, 1006 + { } 1007 + }; 1008 + 998 1009 #endif /* CONFIG_X86 */ 999 1010 1000 1011 #ifdef CONFIG_PNP ··· 1325 1314 1326 1315 if (dmi_check_system(i8042_dmi_kbdreset_table)) 1327 1316 i8042_kbdreset = true; 1317 + 1318 + if (dmi_check_system(i8042_dmi_probe_defer_table)) 1319 + i8042_probe_defer = true; 1328 1320 1329 1321 /* 1330 1322 * A20 was already enabled during early kernel init. But some buggy
+35 -19
drivers/input/serio/i8042.c
··· 45 45 module_param_named(unlock, i8042_unlock, bool, 0); 46 46 MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); 47 47 48 + static bool i8042_probe_defer; 49 + module_param_named(probe_defer, i8042_probe_defer, bool, 0); 50 + MODULE_PARM_DESC(probe_defer, "Allow deferred probing."); 51 + 48 52 enum i8042_controller_reset_mode { 49 53 I8042_RESET_NEVER, 50 54 I8042_RESET_ALWAYS, ··· 715 711 * LCS/Telegraphics. 716 712 */ 717 713 718 - static int __init i8042_check_mux(void) 714 + static int i8042_check_mux(void) 719 715 { 720 716 unsigned char mux_version; 721 717 ··· 744 740 /* 745 741 * The following is used to test AUX IRQ delivery. 746 742 */ 747 - static struct completion i8042_aux_irq_delivered __initdata; 748 - static bool i8042_irq_being_tested __initdata; 743 + static struct completion i8042_aux_irq_delivered; 744 + static bool i8042_irq_being_tested; 749 745 750 - static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) 746 + static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id) 751 747 { 752 748 unsigned long flags; 753 749 unsigned char str, data; ··· 774 770 * verifies success by readinng CTR. Used when testing for presence of AUX 775 771 * port. 776 772 */ 777 - static int __init i8042_toggle_aux(bool on) 773 + static int i8042_toggle_aux(bool on) 778 774 { 779 775 unsigned char param; 780 776 int i; ··· 802 798 * the presence of an AUX interface. 803 799 */ 804 800 805 - static int __init i8042_check_aux(void) 801 + static int i8042_check_aux(void) 806 802 { 807 803 int retval = -1; 808 804 bool irq_registered = false; ··· 1009 1005 1010 1006 if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { 1011 1007 pr_err("Can't read CTR while initializing i8042\n"); 1012 - return -EIO; 1008 + return i8042_probe_defer ? -EPROBE_DEFER : -EIO; 1013 1009 } 1014 1010 1015 1011 } while (n < 2 || ctr[0] != ctr[1]); ··· 1324 1320 i8042_controller_reset(false); 1325 1321 } 1326 1322 1327 - static int __init i8042_create_kbd_port(void) 1323 + static int i8042_create_kbd_port(void) 1328 1324 { 1329 1325 struct serio *serio; 1330 1326 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; ··· 1353 1349 return 0; 1354 1350 } 1355 1351 1356 - static int __init i8042_create_aux_port(int idx) 1352 + static int i8042_create_aux_port(int idx) 1357 1353 { 1358 1354 struct serio *serio; 1359 1355 int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; ··· 1390 1386 return 0; 1391 1387 } 1392 1388 1393 - static void __init i8042_free_kbd_port(void) 1389 + static void i8042_free_kbd_port(void) 1394 1390 { 1395 1391 kfree(i8042_ports[I8042_KBD_PORT_NO].serio); 1396 1392 i8042_ports[I8042_KBD_PORT_NO].serio = NULL; 1397 1393 } 1398 1394 1399 - static void __init i8042_free_aux_ports(void) 1395 + static void i8042_free_aux_ports(void) 1400 1396 { 1401 1397 int i; 1402 1398 ··· 1406 1402 } 1407 1403 } 1408 1404 1409 - static void __init i8042_register_ports(void) 1405 + static void i8042_register_ports(void) 1410 1406 { 1411 1407 int i; 1412 1408 ··· 1447 1443 i8042_aux_irq_registered = i8042_kbd_irq_registered = false; 1448 1444 } 1449 1445 1450 - static int __init i8042_setup_aux(void) 1446 + static int i8042_setup_aux(void) 1451 1447 { 1452 1448 int (*aux_enable)(void); 1453 1449 int error; ··· 1489 1485 return error; 1490 1486 } 1491 1487 1492 - static int __init i8042_setup_kbd(void) 1488 + static int i8042_setup_kbd(void) 1493 1489 { 1494 1490 int error; 1495 1491 ··· 1539 1535 return 0; 1540 1536 } 1541 1537 1542 - static int __init i8042_probe(struct platform_device *dev) 1538 + static int i8042_probe(struct platform_device *dev) 1543 1539 { 1544 1540 int error; 1545 1541 ··· 1604 1600 .pm = &i8042_pm_ops, 1605 1601 #endif 1606 1602 }, 1603 + .probe = i8042_probe, 1607 1604 .remove = i8042_remove, 1608 1605 .shutdown = i8042_shutdown, 1609 1606 }; ··· 1615 1610 1616 1611 static int __init i8042_init(void) 1617 1612 { 1618 - struct platform_device *pdev; 1619 1613 int err; 1620 1614 1621 1615 dbg_init(); ··· 1630 1626 /* Set this before creating the dev to allow i8042_command to work right away */ 1631 1627 i8042_present = true; 1632 1628 1633 - pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); 1634 - if (IS_ERR(pdev)) { 1635 - err = PTR_ERR(pdev); 1629 + err = platform_driver_register(&i8042_driver); 1630 + if (err) 1636 1631 goto err_platform_exit; 1632 + 1633 + i8042_platform_device = platform_device_alloc("i8042", -1); 1634 + if (!i8042_platform_device) { 1635 + err = -ENOMEM; 1636 + goto err_unregister_driver; 1637 1637 } 1638 + 1639 + err = platform_device_add(i8042_platform_device); 1640 + if (err) 1641 + goto err_free_device; 1638 1642 1639 1643 bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block); 1640 1644 panic_blink = i8042_panic_blink; 1641 1645 1642 1646 return 0; 1643 1647 1648 + err_free_device: 1649 + platform_device_put(i8042_platform_device); 1650 + err_unregister_driver: 1651 + platform_driver_unregister(&i8042_driver); 1644 1652 err_platform_exit: 1645 1653 i8042_platform_exit(); 1646 1654 return err;