Pull acpi_bus_register_driver into release branch
[pandora-kernel.git] / drivers / input / joystick / amijoy.c
index e996183..7249d32 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
+#include <linux/mutex.h>
 
 #include <asm/system.h>
 #include <asm/amigahw.h>
@@ -52,12 +53,10 @@ MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is
 __obsolete_setup("amijoy=");
 
 static int amijoy_used;
-static DECLARE_MUTEX(amijoy_sem);
-static struct input_dev amijoy_dev[2];
+static DEFINE_MUTEX(amijoy_mutex);
+static struct input_dev *amijoy_dev[2];
 static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
 
-static char *amijoy_name = "Amiga joystick";
-
 static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
 {
        int i, data = 0, button = 0;
@@ -66,19 +65,19 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
                if (amijoy[i]) {
 
                        switch (i) {
-                               case 0: data = ~custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
-                               case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
+                               case 0: data = ~amiga_custom.joy0dat; button = (~ciaa.pra >> 6) & 1; break;
+                               case 1: data = ~amiga_custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
                        }
 
-                       input_regs(amijoy_dev + i, fp);
+                       input_regs(amijoy_dev[i], fp);
 
-                       input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
+                       input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
 
-                       input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
+                       input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
                        data = ~(data ^ (data << 1));
-                       input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
+                       input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
 
-                       input_sync(amijoy_dev + i);
+                       input_sync(amijoy_dev[i]);
                }
        return IRQ_HANDLED;
 }
@@ -87,7 +86,7 @@ static int amijoy_open(struct input_dev *dev)
 {
        int err;
 
-       err = down_interruptible(&amijoy_sem);
+       err = mutex_lock_interruptible(&amijoy_mutex);
        if (err)
                return err;
 
@@ -99,54 +98,67 @@ static int amijoy_open(struct input_dev *dev)
 
        amijoy_used++;
 out:
-       up(&amijoy_sem);
+       mutex_unlock(&amijoy_mutex);
        return err;
 }
 
 static void amijoy_close(struct input_dev *dev)
 {
-       down(&amijoy_sem);
+       mutex_lock(&amijoy_mutex);
        if (!--amijoy_used)
                free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
-       up(&amijoy_sem);
+       mutex_unlock(&amijoy_mutex);
 }
 
 static int __init amijoy_init(void)
 {
        int i, j;
+       int err;
 
-       for (i = 0; i < 2; i++)
-               if (amijoy[i]) {
-                       if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
-                                               "amijoy [Denise]")) {
-                               if (i == 1 && amijoy[0]) {
-                                       input_unregister_device(amijoy_dev);
-                                       release_mem_region(CUSTOM_PHYSADDR+10, 2);
-                               }
-                               return -EBUSY;
-                       }
+       for (i = 0; i < 2; i++) {
+               if (!amijoy[i])
+                       continue;
 
-                       amijoy_dev[i].open = amijoy_open;
-                       amijoy_dev[i].close = amijoy_close;
-                       amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-                       amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-                       amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-                       for (j = 0; j < 2; j++) {
-                               amijoy_dev[i].absmin[ABS_X + j] = -1;
-                               amijoy_dev[i].absmax[ABS_X + j] = 1;
-                       }
+               amijoy_dev[i] = input_allocate_device();
+               if (!amijoy_dev[i]) {
+                       err = -ENOMEM;
+                       goto fail;
+               }
 
-                       amijoy_dev[i].name = amijoy_name;
-                       amijoy_dev[i].phys = amijoy_phys[i];
-                       amijoy_dev[i].id.bustype = BUS_AMIGA;
-                       amijoy_dev[i].id.vendor = 0x0001;
-                       amijoy_dev[i].id.product = 0x0003;
-                       amijoy_dev[i].id.version = 0x0100;
+               if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
+                       input_free_device(amijoy_dev[i]);
+                       err = -EBUSY;
+                       goto fail;
+               }
 
-                       input_register_device(amijoy_dev + i);
-                       printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
+               amijoy_dev[i]->name = "Amiga joystick";
+               amijoy_dev[i]->phys = amijoy_phys[i];
+               amijoy_dev[i]->id.bustype = BUS_AMIGA;
+               amijoy_dev[i]->id.vendor = 0x0001;
+               amijoy_dev[i]->id.product = 0x0003;
+               amijoy_dev[i]->id.version = 0x0100;
+
+               amijoy_dev[i]->open = amijoy_open;
+               amijoy_dev[i]->close = amijoy_close;
+
+               amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+               amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+               for (j = 0; j < 2; j++) {
+                       amijoy_dev[i]->absmin[ABS_X + j] = -1;
+                       amijoy_dev[i]->absmax[ABS_X + j] = 1;
                }
+
+               input_register_device(amijoy_dev[i]);
+       }
        return 0;
+
+ fail: while (--i >= 0)
+               if (amijoy[i]) {
+                       input_unregister_device(amijoy_dev[i]);
+                       release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
+               }
+       return err;
 }
 
 static void __exit amijoy_exit(void)
@@ -155,8 +167,8 @@ static void __exit amijoy_exit(void)
 
        for (i = 0; i < 2; i++)
                if (amijoy[i]) {
-                       input_unregister_device(amijoy_dev + i);
-                       release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
+                       input_unregister_device(amijoy_dev[i]);
+                       release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
                }
 }