budget-ci fixes and IR-related reorganisation Fix a possible null-dereference in msp430_ir_deinit (which can occur if the call to input_allocate_device() in msp430_ir_init failed). Add a "physical ID" string for the input device. Reorganise the budget_ci struct a little, putting the input-related bits in a substructure. Use a macro for the key repeat delay. Be slightly more informative about IR input initialisation. Signed-Off-By: Darren Salt Index: linux/drivers/media/dvb/ttpci/budget-ci.c =================================================================== RCS file: /cvs/video4linux/v4l-dvb/linux/drivers/media/dvb/ttpci/budget-ci.c,v retrieving revision 1.46 diff -u -p -r1.46 budget-ci.c --- linux/drivers/media/dvb/ttpci/budget-ci.c 4 Dec 2005 01:12:43 -0000 1.46 +++ linux/drivers/media/dvb/ttpci/budget-ci.c 20 Dec 2005 19:14:33 -0000 @@ -62,14 +62,21 @@ #define SLOTSTATUS_READY 8 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) +#define IR_REPEAT_DELAY 350 + +struct budget_ci_ir { + struct input_dev *dev; + char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ + char phys[32]; +}; + struct budget_ci { struct budget budget; - struct input_dev *input_dev; struct tasklet_struct msp430_irq_tasklet; struct tasklet_struct ciintf_irq_tasklet; int slot_status; struct dvb_ca_en50221 ca; - char ir_dev_name[50]; + struct budget_ci_ir ir; u8 tuner_pll_address; /* used for philips_tdm1316l configs */ }; @@ -145,7 +152,7 @@ static void msp430_ir_debounce(unsigned static void msp430_ir_interrupt(unsigned long data) { struct budget_ci *budget_ci = (struct budget_ci *) data; - struct input_dev *dev = budget_ci->input_dev; + struct input_dev *dev = budget_ci->ir.dev; unsigned int code = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; @@ -170,8 +177,7 @@ static void msp430_ir_interrupt(unsigned dev->repeat_key = code; /* Zenith remote _always_ sends 2 sequences */ dev->rep[0] = ~0; - /* 350 milliseconds */ - dev->timer.expires = jiffies + HZ * 350 / 1000; + dev->timer.expires = jiffies + HZ * IR_REPEAT_DELAY / 1000; /* MAKE */ input_event(dev, EV_KEY, key_map[code], !0); add_timer(&dev->timer); @@ -184,41 +190,64 @@ static int msp430_ir_init(struct budget_ struct input_dev *input_dev; int i; - budget_ci->input_dev = input_dev = input_allocate_device(); + budget_ci->ir.dev = input_dev = input_allocate_device(); if (!input_dev) + { + printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); return -ENOMEM; + } - sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name); + snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), "Budget-CI dvb ir receiver %s", saa->name); + snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), "pci-%s/ir0", pci_name(saa->pci)); - input_dev->name = budget_ci->ir_dev_name; + input_dev->name = budget_ci->ir.name; set_bit(EV_KEY, input_dev->evbit); for (i = 0; i < ARRAY_SIZE(key_map); i++) if (key_map[i]) set_bit(key_map[i], input_dev->keybit); - input_register_device(budget_ci->input_dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + input_dev->phys = budget_ci->ir.phys; + input_dev->id.bustype = BUS_PCI; + input_dev->id.version = 1; + if (saa->pci->subsystem_vendor) { + input_dev->id.vendor = saa->pci->subsystem_vendor; + input_dev->id.product = saa->pci->subsystem_device; + } else { + input_dev->id.vendor = saa->pci->vendor; + input_dev->id.product = saa->pci->device; + } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) + input_dev->cdev.dev = &saa->pci->dev; +#else + input_dev->dev = &saa->pci->dev; +#endif +#endif + input_register_device(input_dev); input_dev->timer.function = msp430_ir_debounce; saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); + printk("budget_ci: IR interface initialised\n"); return 0; } static void msp430_ir_deinit(struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; - struct input_dev *dev = budget_ci->input_dev; + struct input_dev *dev = budget_ci->ir.dev; saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - if (del_timer(&dev->timer)) - input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); - - input_unregister_device(dev); + if (dev) { + if (del_timer(&dev->timer)) + input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0); + input_unregister_device(dev); + } } static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) @@ -1093,7 +1122,7 @@ static int budget_ci_attach(struct saa71 struct budget_ci *budget_ci; int err; - if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL))) + if (!(budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL))) return -ENOMEM; dprintk(2, "budget_ci: %p\n", budget_ci);