Improve the error checking in the IR init and deinit functions. Based on Darren Salt's dvb-ir patchset. Signed-off-by: David Härdeman <david@xxxxxxxxxxx> Index: v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c =================================================================== --- v4l-dvb.orig/linux/drivers/media/dvb/ttpci/budget-ci.c 2006-10-02 02:00:18.000000000 +0200 +++ v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c 2006-10-02 17:54:29.000000000 +0200 @@ -192,10 +192,15 @@ struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *input_dev = budget_ci->ir.dev; int i; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + int error; +#endif budget_ci->ir.dev = input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; + if (!input_dev) { + error = -ENOMEM; + goto out1; + } snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), "Budget-CI dvb ir receiver %s", saa->name); @@ -227,14 +232,30 @@ if (key_map[i]) set_bit(key_map[i], input_dev->keybit); - input_register_device(budget_ci->ir.dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + error = input_register_device(input_dev); + if (error) { + printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); + goto out2; + } +#else + input_register_device(input_dev); +#endif input_dev->timer.function = msp430_ir_debounce; + tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, + (unsigned long) budget_ci); + saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); return 0; + +out2: + input_free_device(input_dev); +out1: + return error; } static void msp430_ir_deinit(struct budget_ci *budget_ci) @@ -244,6 +265,7 @@ saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); + tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); if (del_timer(&dev->timer)) input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); @@ -1101,8 +1123,11 @@ struct budget_ci *budget_ci; int err; - if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL))) - return -ENOMEM; + budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL); + if (!budget_ci) { + err = -ENOMEM; + goto out1; + } dprintk(2, "budget_ci: %p\n", budget_ci); @@ -1110,15 +1135,13 @@ dev->ext_priv = budget_ci; - if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) { - kfree(budget_ci); - return err; - } - - tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, - (unsigned long) budget_ci); - - msp430_ir_init(budget_ci); + err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE); + if (err) + goto out2; + + err = msp430_ir_init(budget_ci); + if (err) + goto out3; ciintf_init(budget_ci); @@ -1128,6 +1151,13 @@ ttpci_budget_init_hooks(&budget_ci->budget); return 0; + +out3: + ttpci_budget_deinit(&budget_ci->budget); +out2: + kfree(budget_ci); +out1: + return err; } static int budget_ci_detach(struct saa7146_dev *dev) @@ -1138,16 +1168,13 @@ if (budget_ci->budget.ci_present) ciintf_deinit(budget_ci); + msp430_ir_deinit(budget_ci); if (budget_ci->budget.dvb_frontend) { dvb_unregister_frontend(budget_ci->budget.dvb_frontend); dvb_frontend_detach(budget_ci->budget.dvb_frontend); } err = ttpci_budget_deinit(&budget_ci->budget); - tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); - - msp430_ir_deinit(budget_ci); - // disable frontend and CI interface saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); -- David Härdeman _______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb