diff options
Diffstat (limited to 'drivers/input/mouse/olpc.c')
-rw-r--r-- | drivers/input/mouse/olpc.c | 109 |
1 files changed, 67 insertions, 42 deletions
diff --git a/drivers/input/mouse/olpc.c b/drivers/input/mouse/olpc.c index af6169f1bfb1..4d7adbfb3c01 100644 --- a/drivers/input/mouse/olpc.c +++ b/drivers/input/mouse/olpc.c @@ -69,7 +69,7 @@ static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y) /* My car gets forty rods to the hogshead and that's the * way I likes it! */ - psmouse_queue_work(psmouse, &priv->recalib_wq, + queue_delayed_work(kpsmoused_wq, &priv->recalib_wq, msecs_to_jiffies(1000)); } } @@ -93,30 +93,33 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, int l, int r, int x, int y) { struct hgpk_data *priv = psmouse->private; + static int count; + static int x_tally; + static int y_tally; /* ignore button press packets; many in a row could trigger * a false-positive! */ if (l || r) return; - priv->count++; - priv->x_tally += x; - priv->y_tally += y; - if (priv->count > 100) { - if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { + count++; + x_tally += x; + y_tally += y; + if (count > 100) { + if (abs(x_tally) < 3 && abs(y_tally) < 3) { hgpk_dbg(psmouse, "packet spew detected (%d,%d). :(\n", - priv->x_tally, priv->y_tally); + x_tally, y_tally); /* We had to say dickety 'cause that Kaiser had * stolen our word twenty. I chased that rascal to * get it back, but gave up after dickety six miles */ - psmouse_queue_work(psmouse, &priv->recalib_wq, + queue_delayed_work(kpsmoused_wq, &priv->recalib_wq, msecs_to_jiffies(1000)); } /* reset every 100 packets */ - priv->count = 0; - priv->x_tally = 0; - priv->y_tally = 0; + count = 0; + x_tally = 0; + y_tally = 0; } } @@ -189,7 +192,7 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) * window, schedule another recalibration. */ hgpk_dbg(psmouse, "packet inside calibration window, queueing another recalibration\n"); - psmouse_queue_work(psmouse, &priv->recalib_wq, + queue_delayed_work(kpsmoused_wq, &priv->recalib_wq, msecs_to_jiffies(1000)); } priv->recalib_window = 0; @@ -284,16 +287,9 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable) psmouse_reset(psmouse); - /* should be all set, enable the touchpad */ - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); - psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); - } else { hgpk_dbg(psmouse, "Powering off touchpad.\n"); - - if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) - return -1; - psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); + psmouse_set_state(psmouse, PSMOUSE_IGNORE); if (ps2_command(ps2dev, NULL, 0xec) || ps2_command(ps2dev, NULL, 0xec) || @@ -323,47 +319,77 @@ static int hgpk_reconnect(struct psmouse *psmouse) return 0; } -static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) +static ssize_t hgpk_show_pwred(struct device *dev, + struct device_attribute *attr, char *buf) { + struct serio *serio = to_serio_port(dev); + struct psmouse *psmouse; struct hgpk_data *priv; + int retval; + retval = serio_pin_driver(serio); + if (retval) + return retval; + + psmouse = serio_get_drvdata(serio); priv = psmouse->private; - return sprintf(buf, "%d\n", priv->powered); + + retval = sprintf(buf, "%d\n", priv->powered); + serio_unpin_driver(serio); + return retval; } -static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data, - const char *buf, size_t count) +static ssize_t hgpk_set_pwred(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { + struct serio *serio = to_serio_port(dev); + struct psmouse *psmouse; struct hgpk_data *priv; - unsigned long value; - int err; - - err = strict_strtoul(buf, 10, &value); - if (err || value > 1) + unsigned long val; + int retval; + + if (*buf == '1') + val = 1; + else if (*buf == '0') + val = 0; + else return -EINVAL; + retval = serio_pin_driver(serio); + if (retval) + return retval; + +/* + * FUCK IT. I don't fucking care. locking in psmouse is fucking retarded! + retval = mutex_lock_interruptible(&psmouse_mutex); + if (retval) + goto out_unpin; +*/ + + psmouse = serio_get_drvdata(serio); priv = psmouse->private; - if (value == priv->powered) - return count; - /* hgpk_toggle_power will deal w/ state so we're not racing w/ irq */ - err = hgpk_toggle_power(psmouse, value); - if (!err) - priv->powered = value; + if (val == priv->powered) + goto done; + + retval = hgpk_toggle_power(psmouse, val); + if (!retval) + priv->powered = val; - return err ? err : count; +done: + serio_unpin_driver(serio); + return retval ? retval : count; } -__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, hgpk_show_powered, - hgpk_set_powered, 0); +static DEVICE_ATTR(pwred, S_IWUSR | S_IRUGO, hgpk_show_pwred, hgpk_set_pwred); static void hgpk_disconnect(struct psmouse *psmouse) { struct hgpk_data *priv = psmouse->private; - device_remove_file(&psmouse->ps2dev.serio->dev, - &psmouse_attr_powered.dattr); + device_remove_file(&psmouse->ps2dev.serio->dev, &dev_attr_pwred); psmouse_reset(psmouse); + flush_scheduled_work(); kfree(priv); } @@ -409,8 +435,7 @@ static int hgpk_init(struct psmouse *psmouse) /* Reset after a lot of bad bytes. */ psmouse->resetafter = 1024; - err = device_create_file(&psmouse->ps2dev.serio->dev, - &psmouse_attr_powered.dattr); + err = device_create_file(&psmouse->ps2dev.serio->dev, &dev_attr_pwred); if (err) hgpk_err(psmouse, "Failed to create sysfs attribute\n"); |