Cleanups and drop dual workqueues

Andres Salomon dilinger at debian.unroutableorg
Wed Jan 3 03:36:24 EST 2007


Commit:     9fd3c2a295c5317ab0c275b96254f33952071952
Parent:     8485f7da25c9cf3ddde5ab2d3134e1b3c85f9aaf
commit 9fd3c2a295c5317ab0c275b96254f33952071952
Author:     Andres Salomon <dilinger at debian.org>
AuthorDate: Wed Dec 27 15:28:48 2006 -0500
Commit:     Andres Salomon <dilinger at debian.org>
CommitDate: Wed Dec 27 15:28:48 2006 -0500

    Cleanups and drop dual workqueues
    
    There's no need for two workqueues; drop one of them.  A few further cleanups
    as well, including some better logic for detecting what to do during a mode
    switch and how to handle fast switches from the touchpad hardware.
    
    Signed-off-by: Andres Salomon <dilinger at debian.org>
---
 drivers/input/mouse/olpc.c |  116 +++++++++++++++-----------------------------
 drivers/input/mouse/olpc.h |    3 -
 2 files changed, 41 insertions(+), 78 deletions(-)

diff --git a/drivers/input/mouse/olpc.c b/drivers/input/mouse/olpc.c
index 0ce3a61..e2cd563 100644
--- a/drivers/input/mouse/olpc.c
+++ b/drivers/input/mouse/olpc.c
@@ -33,6 +33,7 @@
 #include <linux/input.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
+#include <linux/delay.h>
 
 #include "psmouse.h"
 #include "olpc.h"
@@ -134,26 +135,22 @@ static void olpc_process_packet_gspt(str
 	input_sync(dev);
 	input_sync(dev2);
 
-	if (!priv->pending_mode)
-		goto switch_mode;
+	if (priv->i->flags & (OLPC_PT|OLPC_GS)) {
+		int pending = 0;
+		if (psmouse->packet[0] == OLPC_PKT_PT && !pt_down)
+			pending = OLPC_GS;
+		else if (psmouse->packet[0] == OLPC_PKT_GS && pt_down)
+			pending = OLPC_PT;
 
-	if (priv->pending_mode == OLPC_GS && pt_down) {
-		priv->pending_mode = 0;
-		cancel_delayed_work(&priv->modeswitch_work_0);
-	}
-
-	return;
-
-switch_mode:
-	if (priv->i->flags & OLPC_PT && priv->i->flags & OLPC_GS) {
-		if (psmouse->packet[0] == OLPC_PKT_PT && !pt_down) {
-			printk(KERN_WARNING "Scheduling switch to GS.\n");
-			priv->pending_mode = OLPC_GS;
-			queue_work(kpsmoused_wq, &priv->modeswitch_work_0);
-		} else if (psmouse->packet[0] == OLPC_PKT_GS && pt_down) {
-			printk(KERN_WARNING "Scheduling switch to PT.\n");
-			priv->pending_mode = OLPC_PT;
-			queue_work(kpsmoused_wq, &priv->modeswitch_work_0);
+		if (priv->current_mode == pending) {
+			priv->pending_mode = 0;
+			pending = priv->current_mode;
+		}
+		else if (priv->pending_mode != pending) {
+			priv->pending_mode = pending;
+			printk(KERN_WARNING "Scheduling mode switch to %s.\n",
+					pending == OLPC_GS ? "GS" : "PT");
+			queue_work(kpsmoused_wq, &priv->mode_switch);
 		}
 	}
 }
@@ -318,26 +315,22 @@ static void olpc_disconnect(struct psmou
 	kfree(priv);
 }
 
-static void olpc_switch_mode_0 (void *p)
+static void olpc_mode_switch(void *p)
 {
 	struct psmouse *psmouse = p;
 	struct olpc_data *priv = psmouse->private;
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	int pending_mode, ret, count;
+	int pending_mode, ret;
 	unsigned char param[3];
 
-	pending_mode = priv->pending_mode;
-	if (!pending_mode) {
-		printk (KERN_WARNING __FILE__ ": In switch_mode, no target mode.\n");
-		return;
-	}
-	if (pending_mode == priv->current_mode && 0) {
-		printk (KERN_WARNING __FILE__ ": In switch_mode, pending == current.\n");
+	if (priv->pending_mode == priv->current_mode) {
+		priv->pending_mode = 0;
+		printk (KERN_DEBUG __FILE__ ": In switch_mode, no target mode.\n");
 		return;
 	}
 
 	if (tpdebug)
-		printk(KERN_WARNING __FILE__ ": Disable for switch to %d. [%lu]\n", pending_mode, jiffies);
+		printk(KERN_WARNING __FILE__ ": Disable for switch to %d. [%lu]\n", priv->pending_mode, jiffies);
 
 	/* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
 	psmouse->state = PSMOUSE_INITIALIZING;
@@ -345,31 +338,13 @@ static void olpc_switch_mode_0 (void *p)
 	ret = ps2_command(ps2dev, NULL, 0xF5);
 	if (ret) {
 		/* XXX: if this ever fails, we need to do a full reset! */
-		printk(KERN_WARNING __FILE__ ": Disable failed for switch to %d. (%d) [%lu]\n", pending_mode, ret, jiffies);
+		printk(KERN_WARNING __FILE__ ": Disable failed for switch to %d. (%d) [%lu]\n", priv->pending_mode, ret, jiffies);
 		return;
 	}
 
-	/* Wait 20ms, then continue. */
-	queue_delayed_work(kpsmoused_wq, &priv->modeswitch_work_1, HZ/10);
-}
-
-static void olpc_switch_mode_1 (void *p)
-{
-	struct psmouse *psmouse = p;
-	struct olpc_data *priv = psmouse->private;
-	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[3];
-	int ret = 0, pending_mode, count;
-
+	/* give it 20ms for the device to be disabled */
+	msleep(20);
 	pending_mode = priv->pending_mode;
-	if (!pending_mode) {
-		printk (KERN_WARNING __FILE__ ": In switch_mode, no target mode.\n");
-		return;
-	}
-	if (pending_mode == priv->current_mode && 0) {
-		printk (KERN_WARNING __FILE__ ": In switch_mode, pending == current.\n");
-		return;
-	}
 
 	if (tpdebug)
 		printk(KERN_WARNING __FILE__ ": Switching to %d. [%lu]\n", pending_mode, jiffies);
@@ -387,7 +362,7 @@ static void olpc_switch_mode_1 (void *p)
 		goto bad;
 	}
 
-	switch(pending_mode) {
+	switch (pending_mode) {
 	default:
 		printk(KERN_WARNING __FILE__ ": Invalid tpmode %d. Default to simultaneous mode\n", tpmode);
 	case OLPC_GS: /* GS only */
@@ -404,35 +379,25 @@ static void olpc_switch_mode_1 (void *p)
 		break;
 	}
 
-	count = 0;
-	while (count++ < 5) {
-		/* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
-		psmouse->pktcnt = psmouse->out_of_sync = 0;
-		psmouse->last = jiffies;
-		psmouse->state = PSMOUSE_ACTIVATED;
-
-		ret = ps2_sendbyte(ps2dev, 0xF4, 500);
-		if (!ret) {
-			break;
-		} else if (tpdebug) {
-			printk(KERN_WARNING __FILE__ ": Enable failed for switch to %d. (%d) [%lu]\n", pending_mode, ret, jiffies);
-		}
-		ps2_command(ps2dev, param, 0x03E9);
-	}
-
-	if (tpdebug)
-		printk(KERN_WARNING __FILE__ ": Switched to %d: %d.\n", pending_mode, ret);
+	/* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
+	psmouse->pktcnt = psmouse->out_of_sync = 0;
+	psmouse->last = jiffies;
+	psmouse->state = PSMOUSE_ACTIVATED;
 
-	if (!ret)
+	ret = ps2_command(ps2dev, NULL, 0xF4);
+	if (ret) {
+		printk(KERN_WARNING __FILE__ ": Enable failed for switch to %d. (%d) [%lu]\n", pending_mode, ret, jiffies);
+	}
+	else {
 		priv->current_mode = pending_mode;
+		if (tpdebug)
+			printk(KERN_WARNING __FILE__ ": Switched to %d: %d.\n", pending_mode, ret);
+	}
 	priv->pending_mode = 0;
-
 	return;
 
 bad:
-	printk(KERN_WARNING __FILE__ ": Failure in switching to %d. (%d)  Retrying..\n", pending_mode, ret);
-	/* Delay, restart. */
-	queue_delayed_work(kpsmoused_wq, &priv->modeswitch_work_1, HZ/10);
+	printk(KERN_WARNING __FILE__ ": Failure in switching to %d. (%d)  We need a full reset here!\n", pending_mode, ret);
 }
 
 int olpc_init(struct psmouse *psmouse)
@@ -513,8 +478,7 @@ int olpc_init(struct psmouse *psmouse)
 	/* Reset after a lot of bad bytes. */
 	psmouse->resetafter = 1024;
 
-	INIT_WORK(&priv->modeswitch_work_0, olpc_switch_mode_0, psmouse);
-	INIT_WORK(&priv->modeswitch_work_1, olpc_switch_mode_1, psmouse);
+	INIT_WORK(&priv->mode_switch, olpc_mode_switch, psmouse);
 
 	return 0;
 
diff --git a/drivers/input/mouse/olpc.h b/drivers/input/mouse/olpc.h
index 3b147e8..cf4109b 100644
--- a/drivers/input/mouse/olpc.h
+++ b/drivers/input/mouse/olpc.h
@@ -31,8 +31,7 @@ struct olpc_data {
 	int initial;
 	int pending_mode;
 	int current_mode;
-	struct work_struct modeswitch_work_0;
-	struct work_struct modeswitch_work_1;
+	struct work_struct mode_switch;
 };
 
 


More information about the Commits-kernel mailing list