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