Skip to content

Commit

Permalink
[media] lirc_dev: store cdev in irctl, up maxdevs
Browse files Browse the repository at this point in the history
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@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Jarod Wilson authored and Mauro Carvalho Chehab committed Jun 11, 2011
1 parent 04f561f commit 8de111e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
37 changes: 27 additions & 10 deletions drivers/media/rc/lirc_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ struct irctl {
struct lirc_buffer *buf;
unsigned int chunk_size;

struct cdev *cdev;

struct task_struct *task;
long jiffies_to_wait;
};

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;
Expand Down Expand Up @@ -167,9 +168,13 @@ static struct file_operations lirc_dev_fops = {

static int lirc_cdev_add(struct irctl *ir)
{
int retval;
int retval = -ENOMEM;
struct lirc_driver *d = &ir->d;
struct cdev *cdev = &cdevs[d->minor];
struct cdev *cdev;

cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
if (!cdev)
goto err_out;

if (d->fops) {
cdev_init(cdev, d->fops);
Expand All @@ -180,12 +185,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;
}

Expand Down Expand Up @@ -214,7 +227,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;
}
Expand Down Expand Up @@ -369,7 +382,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;
}

Expand All @@ -380,7 +393,7 @@ int lirc_unregister_driver(int minor)
return -ENOENT;
}

cdev = &cdevs[minor];
cdev = ir->cdev;

mutex_lock(&lirc_dev_lock);

Expand Down Expand Up @@ -410,6 +423,7 @@ int lirc_unregister_driver(int minor)
} else {
lirc_irctl_cleanup(ir);
cdev_del(cdev);
kfree(cdev);
kfree(ir);
irctls[minor] = NULL;
}
Expand Down Expand Up @@ -453,7 +467,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);
Expand Down Expand Up @@ -484,13 +498,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));
Expand All @@ -503,6 +519,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);
}

Expand Down
2 changes: 1 addition & 1 deletion include/media/lirc_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down

0 comments on commit 8de111e

Please sign in to comment.