Skip to content

Commit b188458

Browse files
jwrdegoededtor
authored andcommitted
Input: i8042 - allow insmod to succeed on devices without an i8042 controller
The i8042 module exports several symbols which may be used by other modules. Before this commit it would refuse to load (when built as a module itself) on systems without an i8042 controller. This is a problem specifically for the asus-nb-wmi module. Many Asus laptops support the Asus WMI interface. Some of them have an i8042 controller and need to use i8042_install_filter() to filter some kbd events. Other models do not have an i8042 controller (e.g. they use an USB attached kbd). Before this commit the asus-nb-wmi driver could not be loaded on Asus models without an i8042 controller, when the i8042 code was built as a module (as Arch Linux does) because the module_init function of the i8042 module would fail with -ENODEV and thus the i8042_install_filter symbol could not be loaded. This commit fixes this by exiting from module_init with a return code of 0 if no controller is found. It also adds a i8042_present bool to make the module_exit function a no-op in this case and also adds a check for i8042_present to the exported i8042_command function. The latter i8042_present check should not really be necessary because when builtin that function can already be used on systems without an i8042 controller, but better safe then sorry. Reported-and-tested-by: Marius Iacob <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 33b6c39 commit b188458

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/input/serio/i8042.c

+11-1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ module_param_named(unmask_kbd_data, i8042_unmask_kbd_data, bool, 0600);
122122
MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive data) of normally sanitize-filtered kbd data traffic debug log [pre-condition: i8042.debug=1 enabled]");
123123
#endif
124124

125+
static bool i8042_present;
125126
static bool i8042_bypass_aux_irq_test;
126127
static char i8042_kbd_firmware_id[128];
127128
static char i8042_aux_firmware_id[128];
@@ -343,6 +344,9 @@ int i8042_command(unsigned char *param, int command)
343344
unsigned long flags;
344345
int retval;
345346

347+
if (!i8042_present)
348+
return -1;
349+
346350
spin_lock_irqsave(&i8042_lock, flags);
347351
retval = __i8042_command(param, command);
348352
spin_unlock_irqrestore(&i8042_lock, flags);
@@ -1612,12 +1616,15 @@ static int __init i8042_init(void)
16121616

16131617
err = i8042_platform_init();
16141618
if (err)
1615-
return err;
1619+
return (err == -ENODEV) ? 0 : err;
16161620

16171621
err = i8042_controller_check();
16181622
if (err)
16191623
goto err_platform_exit;
16201624

1625+
/* Set this before creating the dev to allow i8042_command to work right away */
1626+
i8042_present = true;
1627+
16211628
pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
16221629
if (IS_ERR(pdev)) {
16231630
err = PTR_ERR(pdev);
@@ -1636,6 +1643,9 @@ static int __init i8042_init(void)
16361643

16371644
static void __exit i8042_exit(void)
16381645
{
1646+
if (!i8042_present)
1647+
return;
1648+
16391649
platform_device_unregister(i8042_platform_device);
16401650
platform_driver_unregister(&i8042_driver);
16411651
i8042_platform_exit();

0 commit comments

Comments
 (0)