Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / input / joystick / grip.c
index d1500d2..20cb98a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/gameport.h>
 #include <linux/input.h>
+#include <linux/jiffies.h>
 
 #define DRIVER_DESC    "Gravis GrIP protocol joystick driver"
 
@@ -55,7 +56,7 @@ MODULE_LICENSE("GPL");
 
 struct grip {
        struct gameport *gameport;
-       struct input_dev dev[2];
+       struct input_dev *dev[2];
        unsigned char mode[2];
        int reads;
        int bads;
@@ -190,7 +191,10 @@ static void grip_poll(struct gameport *gameport)
 
        for (i = 0; i < 2; i++) {
 
-               dev = grip->dev + i;
+               dev = grip->dev[i];
+               if (!dev)
+                       continue;
+
                grip->reads++;
 
                switch (grip->mode[i]) {
@@ -297,11 +301,12 @@ static void grip_close(struct input_dev *dev)
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
        struct grip *grip;
+       struct input_dev *input_dev;
        unsigned int data[GRIP_LENGTH_XT];
        int i, j, t;
        int err;
 
-       if (!(grip = kcalloc(1, sizeof(struct grip), GFP_KERNEL)))
+       if (!(grip = kzalloc(sizeof(struct grip), GFP_KERNEL)))
                return -ENOMEM;
 
        grip->gameport = gameport;
@@ -339,48 +344,59 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
        gameport_set_poll_handler(gameport, grip_poll);
        gameport_set_poll_interval(gameport, 20);
 
-       for (i = 0; i < 2; i++)
-               if (grip->mode[i]) {
+       for (i = 0; i < 2; i++) {
+               if (!grip->mode[i])
+                       continue;
 
-                       sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
+               grip->dev[i] = input_dev = input_allocate_device();
+               if (!input_dev) {
+                       err = -ENOMEM;
+                       goto fail3;
+               }
 
-                       grip->dev[i].private = grip;
+               sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
 
-                       grip->dev[i].open = grip_open;
-                       grip->dev[i].close = grip_close;
+               input_dev->name = grip_name[grip->mode[i]];
+               input_dev->phys = grip->phys[i];
+               input_dev->id.bustype = BUS_GAMEPORT;
+               input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+               input_dev->id.product = grip->mode[i];
+               input_dev->id.version = 0x0100;
+               input_dev->cdev.dev = &gameport->dev;
+               input_dev->private = grip;
 
-                       grip->dev[i].name = grip_name[grip->mode[i]];
-                       grip->dev[i].phys = grip->phys[i];
-                       grip->dev[i].id.bustype = BUS_GAMEPORT;
-                       grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
-                       grip->dev[i].id.product = grip->mode[i];
-                       grip->dev[i].id.version = 0x0100;
+               input_dev->open = grip_open;
+               input_dev->close = grip_close;
 
-                       grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
-                       for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
+               for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
 
-                               if (j < grip_cen[grip->mode[i]])
-                                       input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2);
-                               else if (j < grip_anx[grip->mode[i]])
-                                       input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0);
-                               else
-                                       input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0);
-                       }
+                       if (j < grip_cen[grip->mode[i]])
+                               input_set_abs_params(input_dev, t, 14, 52, 1, 2);
+                       else if (j < grip_anx[grip->mode[i]])
+                               input_set_abs_params(input_dev, t, 3, 57, 1, 0);
+                       else
+                               input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+               }
 
-                       for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
-                               if (t > 0)
-                                       set_bit(t, grip->dev[i].keybit);
+               for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
+                       if (t > 0)
+                               set_bit(t, input_dev->keybit);
 
-                       printk(KERN_INFO "input: %s on %s\n",
-                               grip_name[grip->mode[i]], gameport->phys);
-                       input_register_device(grip->dev + i);
-               }
+               err = input_register_device(grip->dev[i]);
+               if (err)
+                       goto fail4;
+       }
 
        return 0;
 
-fail2: gameport_close(gameport);
-fail1: gameport_set_drvdata(gameport, NULL);
+ fail4:        input_free_device(grip->dev[i]);
+ fail3:        while (--i >= 0)
+               if (grip->dev[i])
+                       input_unregister_device(grip->dev[i]);
+ fail2:        gameport_close(gameport);
+ fail1:        gameport_set_drvdata(gameport, NULL);
        kfree(grip);
        return err;
 }
@@ -391,8 +407,8 @@ static void grip_disconnect(struct gameport *gameport)
        int i;
 
        for (i = 0; i < 2; i++)
-               if (grip->mode[i])
-                       input_unregister_device(grip->dev + i);
+               if (grip->dev[i])
+                       input_unregister_device(grip->dev[i]);
        gameport_close(gameport);
        gameport_set_drvdata(gameport, NULL);
        kfree(grip);
@@ -401,6 +417,7 @@ static void grip_disconnect(struct gameport *gameport)
 static struct gameport_driver grip_drv = {
        .driver         = {
                .name   = "grip",
+               .owner  = THIS_MODULE,
        },
        .description    = DRIVER_DESC,
        .connect        = grip_connect,