include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[linux-3.10.git] / drivers / input / mouse / trackpoint.c
index 6d9ec9a..0643e49 100644 (file)
@@ -8,10 +8,10 @@
  * Trademarks are the property of their respective owners.
  */
 
+#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/serio.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/input.h>
 #include <linux/libps2.h>
 #include <linux/proc_fs.h>
@@ -90,10 +90,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
        struct trackpoint_attr_data *attr = data;
        unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 255)
+       if (strict_strtoul(buf, 10, &value) || value > 255)
                return -EINVAL;
 
        *field = value;
@@ -118,10 +116,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
        struct trackpoint_attr_data *attr = data;
        unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
        unsigned long value;
-       char *rest;
 
-       value = simple_strtoul(buf, &rest, 10);
-       if (*rest || value > 1)
+       if (strict_strtoul(buf, 10, &value) || value > 1)
                return -EINVAL;
 
        if (attr->inverted)
@@ -183,21 +179,26 @@ static struct attribute_group trackpoint_attr_group = {
        .attrs = trackpoint_attrs,
 };
 
-static void trackpoint_disconnect(struct psmouse *psmouse)
+static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id)
 {
-       sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
+       unsigned char param[2] = { 0 };
 
-       kfree(psmouse->private);
-       psmouse->private = NULL;
+       if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
+               return -1;
+
+       if (param[0] != TP_MAGIC_IDENT)
+               return -1;
+
+       if (firmware_id)
+               *firmware_id = param[1];
+
+       return 0;
 }
 
 static int trackpoint_sync(struct psmouse *psmouse)
 {
-       unsigned char toggle;
        struct trackpoint_data *tp = psmouse->private;
-
-       if (!tp)
-               return -1;
+       unsigned char toggle;
 
        /* Disable features that may make device unusable with this driver */
        trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle);
@@ -263,46 +264,68 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
        tp->ext_dev = TP_DEF_EXT_DEV;
 }
 
-int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+static void trackpoint_disconnect(struct psmouse *psmouse)
 {
-       struct trackpoint_data *priv;
-       struct ps2dev *ps2dev = &psmouse->ps2dev;
-       unsigned char firmware_id;
-       unsigned char button_info;
-       unsigned char param[2];
+       sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
 
-       param[0] = param[1] = 0;
+       kfree(psmouse->private);
+       psmouse->private = NULL;
+}
 
-       if (ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
+static int trackpoint_reconnect(struct psmouse *psmouse)
+{
+       if (trackpoint_start_protocol(psmouse, NULL))
                return -1;
 
-       if (param[0] != TP_MAGIC_IDENT)
+       if (trackpoint_sync(psmouse))
+               return -1;
+
+       return 0;
+}
+
+int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char firmware_id;
+       unsigned char button_info;
+       int error;
+
+       if (trackpoint_start_protocol(psmouse, &firmware_id))
                return -1;
 
        if (!set_properties)
                return 0;
 
-       firmware_id = param[1];
-
        if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
                printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n");
                button_info = 0;
        }
 
-       psmouse->private = priv = kcalloc(1, sizeof(struct trackpoint_data), GFP_KERNEL);
-       if (!priv)
+       psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
+       if (!psmouse->private)
                return -1;
 
        psmouse->vendor = "IBM";
        psmouse->name = "TrackPoint";
 
-       psmouse->reconnect = trackpoint_sync;
+       psmouse->reconnect = trackpoint_reconnect;
        psmouse->disconnect = trackpoint_disconnect;
 
-       trackpoint_defaults(priv);
+       if ((button_info & 0x0f) >= 3)
+               __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+
+       trackpoint_defaults(psmouse->private);
        trackpoint_sync(psmouse);
 
-       sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
+       error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
+       if (error) {
+               printk(KERN_ERR
+                       "trackpoint.c: failed to create sysfs attributes, error: %d\n",
+                       error);
+               kfree(psmouse->private);
+               psmouse->private = NULL;
+               return -1;
+       }
 
        printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
                firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f);