]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
[media] media: lirc_dev: use an IDA instead of an array to keep track of registered...
authorDavid Härdeman <david@hardeman.nu>
Sun, 25 Jun 2017 12:32:05 +0000 (09:32 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Wed, 4 Oct 2017 17:03:21 +0000 (14:03 -0300)
Using the kernel-provided IDA simplifies the code and makes it possible
to remove the lirc_dev_lock mutex.

Signed-off-by: David Härdeman <david@hardeman.nu>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/rc/lirc_dev.c
include/media/lirc_dev.h

index c83fffec06814f6d6bca247fccf14779b93082a6..a2c5ed0181c1bf5985d75bce9257ad8f2d9d4b75 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/cdev.h>
+#include <linux/idr.h>
 
 #include <media/rc-core.h>
 #include <media/lirc.h>
@@ -46,10 +47,9 @@ struct irctl {
        struct cdev cdev;
 };
 
-/* This mutex protects the irctls array */
-static DEFINE_MUTEX(lirc_dev_lock);
-
-static struct irctl *irctls[MAX_IRCTL_DEVICES];
+/* Used to keep track of allocated lirc devices */
+#define LIRC_MAX_DEVICES 256
+static DEFINE_IDA(lirc_ida);
 
 /* Only used for sysfs but defined to void otherwise */
 static struct class *lirc_class;
@@ -69,9 +69,6 @@ static void lirc_release(struct device *ld)
 {
        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);
        kfree(ir);
 }
@@ -109,7 +106,7 @@ static int lirc_allocate_buffer(struct irctl *ir)
 int lirc_register_driver(struct lirc_driver *d)
 {
        struct irctl *ir;
-       unsigned int minor;
+       int minor;
        int err;
 
        if (!d) {
@@ -171,28 +168,17 @@ int lirc_register_driver(struct lirc_driver *d)
                d->rbuf = ir->buf;
        }
 
-       mutex_lock(&lirc_dev_lock);
-
-       /* 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);
+       minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
+       if (minor < 0) {
                lirc_free_buffer(ir);
                kfree(ir);
-               return -ENOMEM;
+               return minor;
        }
 
-       irctls[minor] = ir;
        d->irctl = ir;
        d->minor = minor;
        ir->d.minor = minor;
 
-       mutex_unlock(&lirc_dev_lock);
-
        device_initialize(&ir->dev);
        ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor);
        ir->dev.class = lirc_class;
@@ -206,6 +192,7 @@ int lirc_register_driver(struct lirc_driver *d)
 
        err = cdev_device_add(&ir->cdev, &ir->dev);
        if (err) {
+               ida_simple_remove(&lirc_ida, minor);
                put_device(&ir->dev);
                return err;
        }
@@ -244,6 +231,7 @@ void lirc_unregister_driver(struct lirc_driver *d)
 
        mutex_unlock(&ir->mutex);
 
+       ida_simple_remove(&lirc_ida, d->minor);
        put_device(&ir->dev);
 }
 EXPORT_SYMBOL(lirc_unregister_driver);
@@ -540,7 +528,7 @@ static int __init lirc_dev_init(void)
                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");
        if (retval) {
                class_destroy(lirc_class);
@@ -557,7 +545,7 @@ static int __init lirc_dev_init(void)
 static void __exit lirc_dev_exit(void)
 {
        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");
 }
 
index 8e3894e2d2c88654de76e8d415ae9a47b6819c5d..51c15c050e851e8d8b1a9679f9c8b4098fc7ae1d 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef _LINUX_LIRC_DEV_H
 #define _LINUX_LIRC_DEV_H
 
-#define MAX_IRCTL_DEVICES 8
 #define BUFLEN            16
 
 #include <linux/slab.h>