aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/lirc_dev.c
diff options
context:
space:
mode:
authorDavid Härdeman <david@hardeman.nu>2017-06-25 08:32:05 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2017-10-04 13:03:21 -0400
commit46c8f4771154eb0dc21f5f2bc2640a33e8fe1d02 (patch)
treeceb3f9342ccff3441735eddd94bdb54a891b2508 /drivers/media/rc/lirc_dev.c
parent3381b779a736f4908a64b603ce339ab067e01de7 (diff)
[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: David Härdeman <david@hardeman.nu> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/rc/lirc_dev.c')
-rw-r--r--drivers/media/rc/lirc_dev.c36
1 files changed, 12 insertions, 24 deletions
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index c83fffec0681..a2c5ed0181c1 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -24,6 +24,7 @@
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/cdev.h> 26#include <linux/cdev.h>
27#include <linux/idr.h>
27 28
28#include <media/rc-core.h> 29#include <media/rc-core.h>
29#include <media/lirc.h> 30#include <media/lirc.h>
@@ -46,10 +47,9 @@ struct irctl {
46 struct cdev cdev; 47 struct cdev cdev;
47}; 48};
48 49
49/* This mutex protects the irctls array */ 50/* Used to keep track of allocated lirc devices */
50static DEFINE_MUTEX(lirc_dev_lock); 51#define LIRC_MAX_DEVICES 256
51 52static DEFINE_IDA(lirc_ida);
52static struct irctl *irctls[MAX_IRCTL_DEVICES];
53 53
54/* Only used for sysfs but defined to void otherwise */ 54/* Only used for sysfs but defined to void otherwise */
55static struct class *lirc_class; 55static struct class *lirc_class;
@@ -69,9 +69,6 @@ static void lirc_release(struct device *ld)
69{ 69{
70 struct irctl *ir = container_of(ld, struct irctl, dev); 70 struct irctl *ir = container_of(ld, struct irctl, dev);
71 71
72 mutex_lock(&lirc_dev_lock);
73 irctls[ir->d.minor] = NULL;
74 mutex_unlock(&lirc_dev_lock);
75 lirc_free_buffer(ir); 72 lirc_free_buffer(ir);
76 kfree(ir); 73 kfree(ir);
77} 74}
@@ -109,7 +106,7 @@ out:
109int lirc_register_driver(struct lirc_driver *d) 106int lirc_register_driver(struct lirc_driver *d)
110{ 107{
111 struct irctl *ir; 108 struct irctl *ir;
112 unsigned int minor; 109 int minor;
113 int err; 110 int err;
114 111
115 if (!d) { 112 if (!d) {
@@ -171,28 +168,17 @@ int lirc_register_driver(struct lirc_driver *d)
171 d->rbuf = ir->buf; 168 d->rbuf = ir->buf;
172 } 169 }
173 170
174 mutex_lock(&lirc_dev_lock); 171 minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
175 172 if (minor < 0) {
176 /* find first free slot for driver */
177 for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
178 if (!irctls[minor])
179 break;
180
181 if (minor == MAX_IRCTL_DEVICES) {
182 dev_err(d->dev, "no free slots for drivers!\n");
183 mutex_unlock(&lirc_dev_lock);
184 lirc_free_buffer(ir); 173 lirc_free_buffer(ir);
185 kfree(ir); 174 kfree(ir);
186 return -ENOMEM; 175 return minor;
187 } 176 }
188 177
189 irctls[minor] = ir;
190 d->irctl = ir; 178 d->irctl = ir;
191 d->minor = minor; 179 d->minor = minor;
192 ir->d.minor = minor; 180 ir->d.minor = minor;
193 181
194 mutex_unlock(&lirc_dev_lock);
195
196 device_initialize(&ir->dev); 182 device_initialize(&ir->dev);
197 ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor); 183 ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor);
198 ir->dev.class = lirc_class; 184 ir->dev.class = lirc_class;
@@ -206,6 +192,7 @@ int lirc_register_driver(struct lirc_driver *d)
206 192
207 err = cdev_device_add(&ir->cdev, &ir->dev); 193 err = cdev_device_add(&ir->cdev, &ir->dev);
208 if (err) { 194 if (err) {
195 ida_simple_remove(&lirc_ida, minor);
209 put_device(&ir->dev); 196 put_device(&ir->dev);
210 return err; 197 return err;
211 } 198 }
@@ -244,6 +231,7 @@ void lirc_unregister_driver(struct lirc_driver *d)
244 231
245 mutex_unlock(&ir->mutex); 232 mutex_unlock(&ir->mutex);
246 233
234 ida_simple_remove(&lirc_ida, d->minor);
247 put_device(&ir->dev); 235 put_device(&ir->dev);
248} 236}
249EXPORT_SYMBOL(lirc_unregister_driver); 237EXPORT_SYMBOL(lirc_unregister_driver);
@@ -540,7 +528,7 @@ static int __init lirc_dev_init(void)
540 return PTR_ERR(lirc_class); 528 return PTR_ERR(lirc_class);
541 } 529 }
542 530
543 retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, 531 retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
544 "BaseRemoteCtl"); 532 "BaseRemoteCtl");
545 if (retval) { 533 if (retval) {
546 class_destroy(lirc_class); 534 class_destroy(lirc_class);
@@ -557,7 +545,7 @@ static int __init lirc_dev_init(void)
557static void __exit lirc_dev_exit(void) 545static void __exit lirc_dev_exit(void)
558{ 546{
559 class_destroy(lirc_class); 547 class_destroy(lirc_class);
560 unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); 548 unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
561 pr_info("module unloaded\n"); 549 pr_info("module unloaded\n");
562} 550}
563 551