Input: serio - offload resume to kseriod

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Monday, July 28, 2008 - 10:59 am

Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6aabcd...
Commit:     6aabcdffd1a5f8f5b906696e58069c4f8fced542
Parent:     a822bea7962b500b0bcab41bf3500f7c40ae56b5
Author:     Shaohua Li <shaohua.li@intel.com>
AuthorDate: Thu Jul 3 10:45:38 2008 -0400
Committer:  Dmitry Torokhov <dmitry.torokhov@gmail.com>
CommitDate: Wed Jul 23 14:02:04 2008 -0400

    Input: serio - offload resume to kseriod
    
    When resuming AUX ports psmouse driver calls psmouse_extensions()
    to determine if the attached mouse is still the same, which may take
    a while to complete for generic mice. Offload the resume process to
    kseriod so the rest of the system may continue resuming without
    waiting for the mouse.
    
    Signed-off-by: Shaohua Li <shaohua.li@intel.com>
    Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
 drivers/input/serio/serio.c |   55 +++++++++++++++++++++++++++++--------------
 1 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 78f2abb..2f12d60 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -63,8 +63,9 @@ static LIST_HEAD(serio_list);
 static struct bus_type serio_bus;
 
 static void serio_add_port(struct serio *serio);
-static void serio_reconnect_port(struct serio *serio);
+static int serio_reconnect_port(struct serio *serio);
 static void serio_disconnect_port(struct serio *serio);
+static void serio_reconnect_chain(struct serio *serio);
 static void serio_attach_driver(struct serio_driver *drv);
 
 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
@@ -161,6 +162,7 @@ static void serio_find_driver(struct serio *serio)
 enum serio_event_type {
 	SERIO_RESCAN_PORT,
 	SERIO_RECONNECT_PORT,
+	SERIO_RECONNECT_CHAIN,
 	SERIO_REGISTER_PORT,
 	SERIO_ATTACH_DRIVER,
 };
@@ -315,6 +317,10 @@ static void serio_handle_event(void)
 				serio_find_driver(event->object);
 				break;
 
+			case SERIO_RECONNECT_CHAIN:
+				serio_reconnect_chain(event->object);
+				break;
+
 			case SERIO_ATTACH_DRIVER:
 				serio_attach_driver(event->object);
 				break;
@@ -470,7 +476,7 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
 	if (!strncmp(buf, "none", count)) {
 		serio_disconnect_port(serio);
 	} else if (!strncmp(buf, "reconnect", count)) {
-		serio_reconnect_port(serio);
+		serio_reconnect_chain(serio);
 	} else if (!strncmp(buf, "rescan", count)) {
 		serio_disconnect_port(serio);
 		serio_find_driver(serio);
@@ -620,14 +626,30 @@ static void serio_destroy_port(struct serio *serio)
 }
 
 /*
+ * Reconnect serio port (re-initialize attached device).
+ * If reconnect fails (old device is no longer attached or
+ * there was no device to begin with) we do full rescan in
+ * hope of finding a driver for the port.
+ */
+static int serio_reconnect_port(struct serio *serio)
+{
+	int error = serio_reconnect_driver(serio);
+
+	if (error) {
+		serio_disconnect_port(serio);
+		serio_find_driver(serio);
+	}
+
+	return error;
+}
+
+/*
  * Reconnect serio port and all its children (re-initialize attached devices)
  */
-static void serio_reconnect_port(struct serio *serio)
+static void serio_reconnect_chain(struct serio *serio)
 {
 	do {
-		if (serio_reconnect_driver(serio)) {
-			serio_disconnect_port(serio);
-			serio_find_driver(serio);
+		if (serio_reconnect_port(serio)) {
 			/* Ok, old children are now gone, we are done */
 			break;
 		}
@@ -673,7 +695,7 @@ void serio_rescan(struct serio *serio)
 
 void serio_reconnect(struct serio *serio)
 {
-	serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
+	serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN);
 }
 
 /*
@@ -927,19 +949,16 @@ static int serio_suspend(struct device *dev, pm_message_t state)
 
 static int serio_resume(struct device *dev)
 {
-	struct serio *serio = to_serio_port(dev);
-
-	if (dev->power.power_state.event != PM_EVENT_ON &&
-	    serio_reconnect_driver(serio)) {
-		/*
-		 * Driver re-probing can take a while, so better let kseriod
-		 * deal with it.
-		 */
-		serio_rescan(serio);
+	/*
+	 * Driver reconnect can take a while, so better let kseriod
+	 * deal with it.
+	 */
+	if (dev->power.power_state.event != PM_EVENT_ON) {
+		dev->power.power_state = PMSG_ON;
+		serio_queue_event(to_serio_port(dev), NULL,
+				  SERIO_RECONNECT_PORT);
 	}
 
-	dev->power.power_state = PMSG_ON;
-
 	return 0;
 }
 #endif /* CONFIG_PM */
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Input: serio - offload resume to kseriod, Linux Kernel Mailing ..., (Mon Jul 28, 10:59 am)