@@ -704,6 +704,23 @@ void serio_reconnect(struct serio *serio)
}
EXPORT_SYMBOL(serio_reconnect);
+void serio_bind_manual_driver(struct serio *serio, struct serio_driver *drv)
+{
+ mutex_lock(&serio_mutex);
+ serio->manual_bind = true;
+ serio->manual_drv = &drv->driver;
+ mutex_unlock(&serio_mutex);
+ serio_rescan(serio);
+}
+EXPORT_SYMBOL(serio_bind_manual_driver);
+
+void serio_clear_manual_driver(struct serio *serio)
+{
+ serio->manual_bind = false;
+ serio->manual_drv = NULL;
+}
+EXPORT_SYMBOL(serio_clear_manual_driver);
+
/*
* Submits register request to kseriod for subsequent execution.
* Note that port registration is always asynchronous.
@@ -902,6 +919,9 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
struct serio *serio = to_serio_port(dev);
struct serio_driver *serio_drv = to_serio_driver(drv);
+ if (serio->manual_drv && serio->manual_drv == drv)
+ return serio_match_port(serio_drv->id_table, serio);
+
if (serio->manual_bind || serio_drv->manual_bind)
return 0;
@@ -64,6 +64,9 @@ struct serio {
* may get indigestion when exposed to concurrent access (i8042).
*/
struct mutex *ps2_cmd_mutex;
+
+ /* Used when forcing a driver instead of the default one. */
+ struct device_driver *manual_drv;
};
#define to_serio_port(d) container_of(d, struct serio, dev)
@@ -88,6 +91,8 @@ int serio_open(struct serio *serio, struct serio_driver *drv);
void serio_close(struct serio *serio);
void serio_rescan(struct serio *serio);
void serio_reconnect(struct serio *serio);
+void serio_bind_manual_driver(struct serio *serio, struct serio_driver *drv);
+void serio_clear_manual_driver(struct serio *serio);
irqreturn_t serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags);
void __serio_register_port(struct serio *serio, struct module *owner);
The Lenovo Thinkpads use RMI4 over SMBus in addition to PS/2 for their trackpad. The problem is that the device doesn't enumerate itself besides some registers in PS/2. Once the initial PS/2 initialization has been made, we need a way to unbind psmouse from the touchpad and use a different (dummy) serio driver to not interfere with SMBus. This patch adds the mechanisms to unbind psmouse and use a different serio driver, driver which can be marked as manual_bind to not be picked up by inadvertence. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- no changes in v3 new in v2 --- drivers/input/serio/serio.c | 20 ++++++++++++++++++++ include/linux/serio.h | 5 +++++ 2 files changed, 25 insertions(+)