Commit 46c8f477 authored by David Härdeman's avatar David Härdeman Committed by Mauro Carvalho Chehab

[media] media: lirc_dev: use an IDA instead of an array to keep track of registered devices

Using the kernel-provided IDA simplifies the code and makes it possible
to remove the lirc_dev_lock mutex.
Signed-off-by: default avatarDavid Härdeman <david@hardeman.nu>
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 3381b779
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/cdev.h> #include <linux/cdev.h>
#include <linux/idr.h>
#include <media/rc-core.h> #include <media/rc-core.h>
#include <media/lirc.h> #include <media/lirc.h>
...@@ -46,10 +47,9 @@ struct irctl { ...@@ -46,10 +47,9 @@ struct irctl {
struct cdev cdev; struct cdev cdev;
}; };
/* This mutex protects the irctls array */ /* Used to keep track of allocated lirc devices */
static DEFINE_MUTEX(lirc_dev_lock); #define LIRC_MAX_DEVICES 256
static DEFINE_IDA(lirc_ida);
static struct irctl *irctls[MAX_IRCTL_DEVICES];
/* Only used for sysfs but defined to void otherwise */ /* Only used for sysfs but defined to void otherwise */
static struct class *lirc_class; static struct class *lirc_class;
...@@ -69,9 +69,6 @@ static void lirc_release(struct device *ld) ...@@ -69,9 +69,6 @@ static void lirc_release(struct device *ld)
{ {
struct irctl *ir = container_of(ld, struct irctl, dev); struct irctl *ir = container_of(ld, struct irctl, dev);
mutex_lock(&lirc_dev_lock);
irctls[ir->d.minor] = NULL;
mutex_unlock(&lirc_dev_lock);
lirc_free_buffer(ir); lirc_free_buffer(ir);
kfree(ir); kfree(ir);
} }
...@@ -109,7 +106,7 @@ static int lirc_allocate_buffer(struct irctl *ir) ...@@ -109,7 +106,7 @@ static int lirc_allocate_buffer(struct irctl *ir)
int lirc_register_driver(struct lirc_driver *d) int lirc_register_driver(struct lirc_driver *d)
{ {
struct irctl *ir; struct irctl *ir;
unsigned int minor; int minor;
int err; int err;
if (!d) { if (!d) {
...@@ -171,28 +168,17 @@ int lirc_register_driver(struct lirc_driver *d) ...@@ -171,28 +168,17 @@ int lirc_register_driver(struct lirc_driver *d)
d->rbuf = ir->buf; d->rbuf = ir->buf;
} }
mutex_lock(&lirc_dev_lock); minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
if (minor < 0) {
/* find first free slot for driver */
for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
if (!irctls[minor])
break;
if (minor == MAX_IRCTL_DEVICES) {
dev_err(d->dev, "no free slots for drivers!\n");
mutex_unlock(&lirc_dev_lock);
lirc_free_buffer(ir); lirc_free_buffer(ir);
kfree(ir); kfree(ir);
return -ENOMEM; return minor;
} }
irctls[minor] = ir;
d->irctl = ir; d->irctl = ir;
d->minor = minor; d->minor = minor;
ir->d.minor = minor; ir->d.minor = minor;
mutex_unlock(&lirc_dev_lock);
device_initialize(&ir->dev); device_initialize(&ir->dev);
ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor); ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor);
ir->dev.class = lirc_class; ir->dev.class = lirc_class;
...@@ -206,6 +192,7 @@ int lirc_register_driver(struct lirc_driver *d) ...@@ -206,6 +192,7 @@ int lirc_register_driver(struct lirc_driver *d)
err = cdev_device_add(&ir->cdev, &ir->dev); err = cdev_device_add(&ir->cdev, &ir->dev);
if (err) { if (err) {
ida_simple_remove(&lirc_ida, minor);
put_device(&ir->dev); put_device(&ir->dev);
return err; return err;
} }
...@@ -244,6 +231,7 @@ void lirc_unregister_driver(struct lirc_driver *d) ...@@ -244,6 +231,7 @@ void lirc_unregister_driver(struct lirc_driver *d)
mutex_unlock(&ir->mutex); mutex_unlock(&ir->mutex);
ida_simple_remove(&lirc_ida, d->minor);
put_device(&ir->dev); put_device(&ir->dev);
} }
EXPORT_SYMBOL(lirc_unregister_driver); EXPORT_SYMBOL(lirc_unregister_driver);
...@@ -540,7 +528,7 @@ static int __init lirc_dev_init(void) ...@@ -540,7 +528,7 @@ static int __init lirc_dev_init(void)
return PTR_ERR(lirc_class); return PTR_ERR(lirc_class);
} }
retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
"BaseRemoteCtl"); "BaseRemoteCtl");
if (retval) { if (retval) {
class_destroy(lirc_class); class_destroy(lirc_class);
...@@ -557,7 +545,7 @@ static int __init lirc_dev_init(void) ...@@ -557,7 +545,7 @@ static int __init lirc_dev_init(void)
static void __exit lirc_dev_exit(void) static void __exit lirc_dev_exit(void)
{ {
class_destroy(lirc_class); class_destroy(lirc_class);
unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
pr_info("module unloaded\n"); pr_info("module unloaded\n");
} }
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#ifndef _LINUX_LIRC_DEV_H #ifndef _LINUX_LIRC_DEV_H
#define _LINUX_LIRC_DEV_H #define _LINUX_LIRC_DEV_H
#define MAX_IRCTL_DEVICES 8
#define BUFLEN 16 #define BUFLEN 16
#include <linux/slab.h> #include <linux/slab.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment