Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+12 −24
Original line number Diff line number Diff line
@@ -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");
}

+0 −1
Original line number Diff line number Diff line
@@ -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>