On Fri, 2011-05-27 at 16:01 -0400, Jarod Wilson wrote: > Store the cdev pointer in struct irctl, allocated dynamically as needed, > rather than having a static array. At the same time, recycle some of the > saved memory to nudge the maximum number of lirc devices supported up a > ways -- its not that uncommon these days, now that we have the rc-core > lirc bridge driver, to see a system with at least 4 raw IR receivers. > (consider a mythtv backend with several video capture devices and the > possible need for IR transmit hardware). > > Signed-off-by: Jarod Wilson <jarod@xxxxxxxxxx> > --- > drivers/media/rc/lirc_dev.c | 33 ++++++++++++++++++++++++--------- > include/media/lirc_dev.h | 2 +- > 2 files changed, 25 insertions(+), 10 deletions(-) > > diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c > index fd237ab..9e79692 100644 > --- a/drivers/media/rc/lirc_dev.c > +++ b/drivers/media/rc/lirc_dev.c > @@ -55,6 +55,8 @@ struct irctl { > struct lirc_buffer *buf; > unsigned int chunk_size; > > + struct cdev *cdev; > + > struct task_struct *task; > long jiffies_to_wait; > }; > @@ -62,7 +64,6 @@ struct irctl { > static DEFINE_MUTEX(lirc_dev_lock); > > static struct irctl *irctls[MAX_IRCTL_DEVICES]; > -static struct cdev cdevs[MAX_IRCTL_DEVICES]; > > /* Only used for sysfs but defined to void otherwise */ > static struct class *lirc_class; > @@ -169,7 +170,9 @@ static int lirc_cdev_add(struct irctl *ir) > { > int retval; > struct lirc_driver *d = &ir->d; > - struct cdev *cdev = &cdevs[d->minor]; > + struct cdev *cdev; > + > + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); if (cdev == NULL) > if (d->fops) { > cdev_init(cdev, d->fops); generate_oops(); ;) Regards, Andy > @@ -180,12 +183,20 @@ static int lirc_cdev_add(struct irctl *ir) > } > retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); > if (retval) > - return retval; > + goto err_out; > > retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); > - if (retval) > + if (retval) { > kobject_put(&cdev->kobj); > + goto err_out; > + } > + > + ir->cdev = cdev; > + > + return 0; > > +err_out: > + kfree(cdev); > return retval; > } > > @@ -214,7 +225,7 @@ int lirc_register_driver(struct lirc_driver *d) > if (MAX_IRCTL_DEVICES <= d->minor) { > dev_err(d->dev, "lirc_dev: lirc_register_driver: " > "\"minor\" must be between 0 and %d (%d)!\n", > - MAX_IRCTL_DEVICES-1, d->minor); > + MAX_IRCTL_DEVICES - 1, d->minor); > err = -EBADRQC; > goto out; > } > @@ -369,7 +380,7 @@ int lirc_unregister_driver(int minor) > > if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { > printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " > - "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1); > + "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES - 1); > return -EBADRQC; > } > > @@ -380,7 +391,7 @@ int lirc_unregister_driver(int minor) > return -ENOENT; > } > > - cdev = &cdevs[minor]; > + cdev = ir->cdev; > > mutex_lock(&lirc_dev_lock); > > @@ -410,6 +421,7 @@ int lirc_unregister_driver(int minor) > } else { > lirc_irctl_cleanup(ir); > cdev_del(cdev); > + kfree(cdev); > kfree(ir); > irctls[minor] = NULL; > } > @@ -453,7 +465,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) > goto error; > } > > - cdev = &cdevs[iminor(inode)]; > + cdev = ir->cdev; > if (try_module_get(cdev->owner)) { > ir->open++; > retval = ir->d.set_use_inc(ir->d.data); > @@ -484,13 +496,15 @@ EXPORT_SYMBOL(lirc_dev_fop_open); > int lirc_dev_fop_close(struct inode *inode, struct file *file) > { > struct irctl *ir = irctls[iminor(inode)]; > - struct cdev *cdev = &cdevs[iminor(inode)]; > + struct cdev *cdev; > > if (!ir) { > printk(KERN_ERR "%s: called with invalid irctl\n", __func__); > return -EINVAL; > } > > + cdev = ir->cdev; > + > dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); > > WARN_ON(mutex_lock_killable(&lirc_dev_lock)); > @@ -503,6 +517,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) > lirc_irctl_cleanup(ir); > cdev_del(cdev); > irctls[ir->d.minor] = NULL; > + kfree(cdev); > kfree(ir); > } > > diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h > index 630e702..168dd0b 100644 > --- a/include/media/lirc_dev.h > +++ b/include/media/lirc_dev.h > @@ -9,7 +9,7 @@ > #ifndef _LINUX_LIRC_DEV_H > #define _LINUX_LIRC_DEV_H > > -#define MAX_IRCTL_DEVICES 4 > +#define MAX_IRCTL_DEVICES 8 > #define BUFLEN 16 > > #define mod(n, div) ((n) % (div)) -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html