suspend/resume timings

Jens Axboe olpc-devel at kernel.dk
Tue Apr 3 10:21:59 EDT 2007


On Tue, Apr 03 2007, Jens Axboe wrote:
> On Mon, Apr 02 2007, Marcelo Tosatti wrote:
> > On Sun, Apr 01, 2007 at 09:09:19PM +0200, Jens Axboe wrote:
> > > Hi,
> > > 
> > > I took a look at the time spent doing a suspend and resume cycle. In
> > > general things go pretty fast, most devices handle it really quickly.
> > > USB is a bit slow (~100 msec), but I ignored that since apparently there
> > > are already people working on fixing USB suspend (functionality, speed
> > > of course comes second).
> > > 
> > > The slowest parts are the keyboard and mouse. psmouse takes ~570 msec to
> > > resume alone, and the keyboard is no speed daemon at ~269 msecs. Looking
> > > at the psmouse first, by far the majority of the time is spend resetting
> > > the device (drivers/input/mouse/olpc.c:olpc_reconnect() ->
> > > psmouse_reset()). A quick test works fine for me without the reset, but
> > > that may not be a sound approach. Perhaps deferring a reset to IFF
> > > olpc_get_model() fails would be more safe?
> > > 
> > > I'll be playing some more with the timings and testing over the next
> > > week, do let me know if there's something more urgent in suspend/resume
> > > area that needs attention.
> > > 
> > > The kernel used was current olpc-2.6.
> > 
> > Jens,
> > 
> > What about this patch instead. It avoids the psmouse reconnect method
> > from being called (thus the ps2 command in olpc_get_model()), which
> > saves us a few more milliseconds.
> 
> If you want my honest opinion, I think it's a big hack. If the keyboard
> and mouse are always connected to a live power rail, what makes
> reconnect so special? We should just fix the suspend/resume hooks for
> mouse and keyboard to do only the minimal bits, if anything at all.

This isn't very pretty either, but I think it's a lot more digestable.
Probably the always_on flag should be moved a level below the serio
device.

diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 1d699a1..e4c3894 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1001,6 +1001,10 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 	if (err)
 		goto fail4;
 
+#if defined(CONFIG_OLPC)
+	serio->always_on = 1;
+#endif
+
 	return 0;
 
  fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
diff --git a/drivers/input/mouse/olpc.c b/drivers/input/mouse/olpc.c
index 3ca459e..71c5e38 100644
--- a/drivers/input/mouse/olpc.c
+++ b/drivers/input/mouse/olpc.c
@@ -502,6 +502,7 @@ int olpc_init(struct psmouse *psmouse)
 	psmouse->disconnect = olpc_disconnect;
 	psmouse->reconnect = olpc_reconnect;
 	psmouse->pktsize = 6;
+	psmouse->ps2dev.serio->always_on = 1;
 
 	/* Disable the idle resync. */
 	psmouse->resync_time = 0;
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index a15e531..4fcd399 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -926,8 +926,10 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
 #ifdef CONFIG_PM
 static int serio_suspend(struct device *dev, pm_message_t state)
 {
+	struct serio *serio = to_serio_port(dev);
+
 	if (dev->power.power_state.event != state.event) {
-		if (state.event == PM_EVENT_SUSPEND)
+		if (state.event == PM_EVENT_SUSPEND && !serio->always_on)
 			serio_cleanup(to_serio_port(dev));
 
 		dev->power.power_state = state;
@@ -940,7 +942,7 @@ static int serio_resume(struct device *dev)
 {
 	struct serio *serio = to_serio_port(dev);
 
-	if (dev->power.power_state.event != PM_EVENT_ON &&
+	if (dev->power.power_state.event != PM_EVENT_ON && !serio->always_on &&
 	    serio_reconnect_driver(serio)) {
 		/*
 		 * Driver re-probing can take a while, so better let kseriod
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 1ebf045..623ccef 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -48,6 +48,7 @@ struct serio {
 
 	struct device dev;
 	unsigned int registered;	/* port has been fully registered with driver core */
+	unsigned int always_on;		/* always powered, don't suspend/resume */
 
 	struct list_head node;
 };

-- 
Jens Axboe




More information about the Devel mailing list