summaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/psmouse-base.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2017-03-02 10:48:23 -0800
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2017-03-25 10:37:29 -0700
commit8eb92e5c91338eb19f86ffb2232258337ebf905b (patch)
tree2945e2b7f324c0a3d8da4aebefa27b145ffb7d6f /drivers/input/mouse/psmouse-base.c
parentc774326a219536ab615d68a22875673f6f608b62 (diff)
downloadlinux-8eb92e5c91338eb19f86ffb2232258337ebf905b.tar.bz2
Input: psmouse - add support for SMBus companions
This provides glue between PS/2 devices that enumerate the RMI4 devices and Elan touchpads to the RMI4 (or Elan) SMBus driver. The SMBus devices keep their PS/2 connection alive. If the initialization process goes too far (psmouse_activate called), the device disconnects from the I2C bus and stays on the PS/2 bus, that is why we explicitly disable PS/2 device reporting (by calling psmouse_deactivate) before trying to register SMBus companion device. The HID over I2C devices are enumerated through the ACPI DSDT, and their PS/2 device also exports the InterTouch bit in the extended capability 0x0C. However, the firmware keeps its I2C connection open even after going further in the PS/2 initialization. We don't need to take extra precautions with those device, especially because they block their PS/2 communication when HID over I2C is used. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse/psmouse-base.c')
-rw-r--r--drivers/input/mouse/psmouse-base.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index a84f8ed2ba5d..ab9bfe2af381 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -1999,16 +1999,27 @@ static int __init psmouse_init(void)
synaptics_module_init();
hgpk_module_init();
+ err = psmouse_smbus_module_init();
+ if (err)
+ return err;
+
kpsmoused_wq = alloc_ordered_workqueue("kpsmoused", 0);
if (!kpsmoused_wq) {
pr_err("failed to create kpsmoused workqueue\n");
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_smbus_exit;
}
err = serio_register_driver(&psmouse_drv);
if (err)
- destroy_workqueue(kpsmoused_wq);
+ goto err_destroy_wq;
+ return 0;
+
+err_destroy_wq:
+ destroy_workqueue(kpsmoused_wq);
+err_smbus_exit:
+ psmouse_smbus_module_exit();
return err;
}
@@ -2016,6 +2027,7 @@ static void __exit psmouse_exit(void)
{
serio_unregister_driver(&psmouse_drv);
destroy_workqueue(kpsmoused_wq);
+ psmouse_smbus_module_exit();
}
module_init(psmouse_init);