/* -------------------------------------------------------------------------- */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-                  int ir_type, struct ir_scancode_table *ir_codes)
+                  int ir_type)
 {
        ir->ir_type = ir_type;
 
        if (repeat)
                set_bit(EV_REP, dev->evbit);
 
-       ir_input_register(dev, ir_codes);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(ir_input_init);
 
  *  GNU General Public License for more details.
  */
 
-#include <linux/usb/input.h>
 
+#include <linux/usb/input.h>
 #include <media/ir-common.h>
 
 #define IR_TAB_MIN_SIZE        32
 {
        struct ir_input_dev *ir_dev;
        struct ir_scancode  *keymap    = rc_tab->scan;
-       int i;
+       int i, rc;
 
        if (rc_tab->scan == NULL || !rc_tab->size)
                return -EINVAL;
        input_dev->setkeycode = ir_setkeycode;
        input_set_drvdata(input_dev, ir_dev);
 
-       return 0;
+       rc = input_register_device(input_dev);
+       if (rc < 0) {
+               kfree(rc_tab->scan);
+               kfree(ir_dev);
+               input_set_drvdata(input_dev, NULL);
+       }
+
+       return rc;
 }
 EXPORT_SYMBOL_GPL(ir_input_register);
 
 void ir_input_unregister(struct input_dev *dev)
 {
        struct ir_input_dev *ir_dev = input_get_drvdata(dev);
-       struct ir_scancode_table *rc_tab = &ir_dev->rc_tab;
+       struct ir_scancode_table *rc_tab;
 
-       if (!rc_tab)
+       if (!ir_dev)
                return;
 
        IR_dprintk(1, "Freed keycode table\n");
 
+       rc_tab = &ir_dev->rc_tab;
        rc_tab->size = 0;
        kfree(rc_tab->scan);
        rc_tab->scan = NULL;
 
        kfree(ir_dev);
-       input_set_drvdata(dev, NULL);
+       input_unregister_device(dev);
 }
 EXPORT_SYMBOL_GPL(ir_input_unregister);
 
 
        snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
                "pci-%s/ir0", pci_name(dm1105->pdev));
 
-       err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
+       err = ir_input_init(input_dev, &dm1105->ir.ir, ir_type);
        if (err < 0) {
                input_free_device(input_dev);
                return err;
 
        INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
 
-       err = input_register_device(input_dev);
-       if (err) {
-               ir_input_unregister(input_dev);
-               input_free_device(input_dev);
-               return err;
-       }
+       err = ir_input_register(input_dev, ir_codes);
 
-       return 0;
+       return err;
 }
 
 void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
 {
        ir_input_unregister(dm1105->ir.input_dev);
-       input_unregister_device(dm1105->ir.input_dev);
 }
 
 static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb)
 
        struct saa7146_dev *saa = budget_ci->budget.dev;
        struct input_dev *input_dev = budget_ci->ir.dev;
        int error;
+       struct ir_scancode_table *ir_codes;
+
 
        budget_ci->ir.dev = input_dev = input_allocate_device();
        if (!input_dev) {
                printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
-               error = -ENOMEM;
-               goto out1;
+               return -ENOMEM;
        }
 
        snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
        }
        input_dev->dev.parent = &saa->pci->dev;
 
+       if (rc5_device < 0)
+               budget_ci->ir.rc5_device = IR_DEVICE_ANY;
+       else
+               budget_ci->ir.rc5_device = rc5_device;
+
        /* Select keymap and address */
        switch (budget_ci->budget.dev->pci->subsystem_device) {
        case 0x100c:
        case 0x1011:
        case 0x1012:
                /* The hauppauge keymap is a superset of these remotes */
-               error = ir_input_init(input_dev, &budget_ci->ir.state,
-                             IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
-               if (error < 0)
-                       goto out2;
+               ir_codes = &ir_codes_hauppauge_new_table;
 
                if (rc5_device < 0)
                        budget_ci->ir.rc5_device = 0x1f;
-               else
-                       budget_ci->ir.rc5_device = rc5_device;
                break;
        case 0x1010:
        case 0x1017:
        case 0x101a:
                /* for the Technotrend 1500 bundled remote */
-               error = ir_input_init(input_dev, &budget_ci->ir.state,
-                             IR_TYPE_RC5, &ir_codes_tt_1500_table);
-               if (error < 0)
-                       goto out2;
-
-               if (rc5_device < 0)
-                       budget_ci->ir.rc5_device = IR_DEVICE_ANY;
-               else
-                       budget_ci->ir.rc5_device = rc5_device;
+               ir_codes = &ir_codes_tt_1500_table;
                break;
        default:
                /* unknown remote */
-               error = ir_input_init(input_dev, &budget_ci->ir.state,
-                             IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
-               if (error < 0)
-                       goto out2;
-
-               if (rc5_device < 0)
-                       budget_ci->ir.rc5_device = IR_DEVICE_ANY;
-               else
-                       budget_ci->ir.rc5_device = rc5_device;
+               ir_codes = &ir_codes_budget_ci_old_table;
                break;
        }
 
+       ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5);
+
        /* initialise the key-up timeout handler */
        init_timer(&budget_ci->ir.timer_keyup);
        budget_ci->ir.timer_keyup.function = msp430_ir_keyup;
        budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir;
        budget_ci->ir.last_raw = 0xffff; /* An impossible value */
-       error = input_register_device(input_dev);
+       error = ir_input_register(input_dev, ir_codes);
        if (error) {
                printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
-               goto out2;
+               return error;
        }
 
        /* note: these must be after input_register_device */
        saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
 
        return 0;
-
-out2:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
-out1:
-       return error;
 }
 
 static void msp430_ir_deinit(struct budget_ci *budget_ci)
        ir_input_nokey(dev, &budget_ci->ir.state);
 
        ir_input_unregister(dev);
-       input_unregister_device(dev);
 }
 
 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
 
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
                 pci_name(btv->c.pci));
 
-       err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, ir_type);
        if (err < 0)
                goto err_out_free;
 
        bttv_ir_start(btv, ir);
 
        /* all done */
-       err = input_register_device(btv->remote->dev);
+       err = ir_input_register(btv->remote->dev, ir_codes);
        if (err)
                goto err_out_stop;
 
        bttv_ir_stop(btv);
        btv->remote = NULL;
  err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        bttv_ir_stop(btv);
        ir_input_unregister(btv->remote->dev);
-       input_unregister_device(btv->remote->dev);
        kfree(btv->remote);
        btv->remote = NULL;
 }
 
        usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
        strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-       err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
-                           dev->board.ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
        if (err < 0)
                goto err_out_free;
 
        cx231xx_ir_start(ir);
 
        /* all done */
-       err = input_register_device(ir->input);
+       err = ir_input_register(ir->input, dev->board.ir_codes);
        if (err)
                goto err_out_stop;
 
        cx231xx_ir_stop(ir);
        dev->ir = NULL;
 err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        cx231xx_ir_stop(ir);
        ir_input_unregister(ir->input);
-       input_unregister_device(ir->input);
        kfree(ir);
 
        /* done */
 
                 cx23885_boards[dev->board].name);
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
 
-       ret = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+       ret = ir_input_init(input_dev, &ir->ir, ir_type);
        if (ret < 0)
                goto err_out_free;
 
        dev->ir_input = ir;
        cx23885_input_ir_start(dev);
 
-       ret = input_register_device(ir->dev);
+       ret = ir_input_register(ir->dev, ir_codes);
        if (ret)
                goto err_out_stop;
 
        cx23885_input_ir_stop(dev);
        dev->ir_input = NULL;
 err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return ret;
 }
        if (dev->ir_input == NULL)
                return;
        ir_input_unregister(dev->ir_input->dev);
-       input_unregister_device(dev->ir_input->dev);
        kfree(dev->ir_input);
        dev->ir_input = NULL;
 }
 
        snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
-       err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, ir_type);
        if (err < 0)
                goto err_out_free;
 
        cx88_ir_start(core, ir);
 
        /* all done */
-       err = input_register_device(ir->input);
+       err = ir_input_register(ir->input, ir_codes);
        if (err)
                goto err_out_stop;
 
        cx88_ir_stop(core, ir);
        core->ir = NULL;
  err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        cx88_ir_stop(core, ir);
        ir_input_unregister(ir->input);
-       input_unregister_device(ir->input);
        kfree(ir);
 
        /* done */
 
        usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
        strlcat(ir->phys, "/input0", sizeof(ir->phys));
 
-       err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER,
-                            dev->board.ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
        if (err < 0)
                goto err_out_free;
 
        em28xx_ir_start(ir);
 
        /* all done */
-       err = input_register_device(ir->input);
+       err = ir_input_register(ir->input, dev->board.ir_codes);
        if (err)
                goto err_out_stop;
 
        em28xx_ir_stop(ir);
        dev->ir = NULL;
  err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        em28xx_ir_stop(ir);
        ir_input_unregister(ir->input);
-       input_unregister_device(ir->input);
        kfree(ir);
 
        /* done */
 
                 dev_name(&client->dev));
 
        /* init + register input device */
-       err = ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, ir_type);
        if (err < 0)
                goto err_out_free;
 
        input_dev->name       = ir->name;
        input_dev->phys       = ir->phys;
 
-       err = input_register_device(ir->input);
+       err = ir_input_register(ir->input, ir->ir_codes);
        if (err)
                goto err_out_free;
 
        return 0;
 
  err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        /* unregister device */
        ir_input_unregister(ir->input);
-       input_unregister_device(ir->input);
 
        /* free memory */
        kfree(ir);
 
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
                 pci_name(dev->pci));
 
-       err = ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+       err = ir_input_init(input_dev, &ir->ir, ir_type);
        if (err < 0)
                goto err_out_free;
 
        dev->remote = ir;
        saa7134_ir_start(dev, ir);
 
-       err = input_register_device(ir->dev);
+       err = ir_input_register(ir->dev, ir_codes);
        if (err)
                goto err_out_stop;
 
        saa7134_ir_stop(dev);
        dev->remote = NULL;
  err_out_free:
-       ir_input_unregister(input_dev);
-       input_free_device(input_dev);
        kfree(ir);
        return err;
 }
 
        saa7134_ir_stop(dev);
        ir_input_unregister(dev->remote->dev);
-       input_unregister_device(dev->remote->dev);
        kfree(dev->remote);
        dev->remote = NULL;
 }
 
 /* Routines from ir-functions.c */
 
 int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-                  int ir_type, struct ir_scancode_table *ir_codes);
+                  int ir_type);
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
 void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
                      u32 ir_key);