fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / media / video / bt8xx / bttv-input.c
index 933d6db..cbc012f 100644 (file)
@@ -259,24 +259,59 @@ static void bttv_rc5_timer_keyup(unsigned long data)
 
 /* ---------------------------------------------------------------------- */
 
+static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
+{
+       if (ir->polling) {
+               init_timer(&ir->timer);
+               ir->timer.function = bttv_input_timer;
+               ir->timer.data     = (unsigned long)btv;
+               ir->timer.expires  = jiffies + HZ;
+               add_timer(&ir->timer);
+       } else if (ir->rc5_gpio) {
+               /* set timer_end for code completion */
+               init_timer(&ir->timer_end);
+               ir->timer_end.function = bttv_rc5_timer_end;
+               ir->timer_end.data = (unsigned long)ir;
+
+               init_timer(&ir->timer_keyup);
+               ir->timer_keyup.function = bttv_rc5_timer_keyup;
+               ir->timer_keyup.data = (unsigned long)ir;
+       }
+}
+
+static void bttv_ir_stop(struct bttv *btv)
+{
+       if (btv->remote->polling) {
+               del_timer_sync(&btv->remote->timer);
+               flush_scheduled_work();
+       }
+
+       if (btv->remote->rc5_gpio) {
+               u32 gpio;
+
+               del_timer_sync(&btv->remote->timer_end);
+               flush_scheduled_work();
+
+               gpio = bttv_gpio_read(&btv->c);
+               bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
+       }
+}
+
 int bttv_input_init(struct bttv *btv)
 {
        struct bttv_ir *ir;
        IR_KEYTAB_TYPE *ir_codes = NULL;
        struct input_dev *input_dev;
        int ir_type = IR_TYPE_OTHER;
+       int err = -ENOMEM;
 
        if (!btv->has_remote)
                return -ENODEV;
 
        ir = kzalloc(sizeof(*ir),GFP_KERNEL);
        input_dev = input_allocate_device();
-       if (!ir || !input_dev) {
-               kfree(ir);
-               input_free_device(input_dev);
-               return -ENOMEM;
-       }
-       memset(ir,0,sizeof(*ir));
+       if (!ir || !input_dev)
+               goto err_out_free;
 
        /* detect & configure */
        switch (btv->c.type) {
@@ -348,10 +383,9 @@ int bttv_input_init(struct bttv *btv)
                break;
        }
        if (NULL == ir_codes) {
-               dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
-               kfree(ir);
-               input_free_device(input_dev);
-               return -ENODEV;
+               dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type);
+               err = -ENODEV;
+               goto err_out_free;
        }
 
        if (ir->rc5_gpio) {
@@ -389,32 +423,26 @@ int bttv_input_init(struct bttv *btv)
        input_dev->cdev.dev = &btv->c.pci->dev;
 
        btv->remote = ir;
-       if (ir->polling) {
-               init_timer(&ir->timer);
-               ir->timer.function = bttv_input_timer;
-               ir->timer.data     = (unsigned long)btv;
-               ir->timer.expires  = jiffies + HZ;
-               add_timer(&ir->timer);
-       } else if (ir->rc5_gpio) {
-               /* set timer_end for code completion */
-               init_timer(&ir->timer_end);
-               ir->timer_end.function = bttv_rc5_timer_end;
-               ir->timer_end.data = (unsigned long)ir;
-
-               init_timer(&ir->timer_keyup);
-               ir->timer_keyup.function = bttv_rc5_timer_keyup;
-               ir->timer_keyup.data = (unsigned long)ir;
-       }
+       bttv_ir_start(btv, ir);
 
        /* all done */
-       input_register_device(btv->remote->dev);
-       printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
+       err = input_register_device(btv->remote->dev);
+       if (err)
+               goto err_out_stop;
 
        /* the remote isn't as bouncy as a keyboard */
        ir->dev->rep[REP_DELAY] = repeat_delay;
        ir->dev->rep[REP_PERIOD] = repeat_period;
 
        return 0;
+
+ err_out_stop:
+       bttv_ir_stop(btv);
+       btv->remote = NULL;
+ err_out_free:
+       input_free_device(input_dev);
+       kfree(ir);
+       return err;
 }
 
 void bttv_input_fini(struct bttv *btv)
@@ -422,22 +450,7 @@ void bttv_input_fini(struct bttv *btv)
        if (btv->remote == NULL)
                return;
 
-       if (btv->remote->polling) {
-               del_timer_sync(&btv->remote->timer);
-               flush_scheduled_work();
-       }
-
-
-       if (btv->remote->rc5_gpio) {
-               u32 gpio;
-
-               del_timer_sync(&btv->remote->timer_end);
-               flush_scheduled_work();
-
-               gpio = bttv_gpio_read(&btv->c);
-               bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
-       }
-
+       bttv_ir_stop(btv);
        input_unregister_device(btv->remote->dev);
        kfree(btv->remote);
        btv->remote = NULL;