[media] media: lirc_dev: remove support for manually specifying minor number

All users of lirc_register_driver() uses dynamic minor allocation,
therefore we can remove the ability to explicitly request a given number.

This changes the function prototype of lirc_unregister_driver() to also
take a struct lirc_driver pointer as the sole argument.

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>
This commit is contained in:
David Härdeman 2017-06-25 09:31:24 -03:00 committed by Mauro Carvalho Chehab
parent de226ec8a6
commit c3c6dd750e
4 changed files with 34 additions and 77 deletions

View file

@ -382,7 +382,6 @@ static int ir_lirc_register(struct rc_dev *dev)
snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
dev->driver_name); dev->driver_name);
drv->minor = -1;
drv->features = features; drv->features = features;
drv->data = &dev->raw->lirc; drv->data = &dev->raw->lirc;
drv->rbuf = NULL; drv->rbuf = NULL;
@ -394,11 +393,9 @@ static int ir_lirc_register(struct rc_dev *dev)
drv->rdev = dev; drv->rdev = dev;
drv->owner = THIS_MODULE; drv->owner = THIS_MODULE;
drv->minor = lirc_register_driver(drv); rc = lirc_register_driver(drv);
if (drv->minor < 0) { if (rc < 0)
rc = -ENODEV;
goto out; goto out;
}
dev->raw->lirc.drv = drv; dev->raw->lirc.drv = drv;
dev->raw->lirc.dev = dev; dev->raw->lirc.dev = dev;
@ -413,7 +410,7 @@ static int ir_lirc_unregister(struct rc_dev *dev)
{ {
struct lirc_codec *lirc = &dev->raw->lirc; struct lirc_codec *lirc = &dev->raw->lirc;
lirc_unregister_driver(lirc->drv->minor); lirc_unregister_driver(lirc->drv);
kfree(lirc->drv); kfree(lirc->drv);
lirc->drv = NULL; lirc->drv = NULL;

View file

@ -29,7 +29,6 @@
#include <media/lirc.h> #include <media/lirc.h>
#include <media/lirc_dev.h> #include <media/lirc_dev.h>
#define NOPLUG -1
#define LOGHEAD "lirc_dev (%s[%d]): " #define LOGHEAD "lirc_dev (%s[%d]): "
static dev_t lirc_base_dev; static dev_t lirc_base_dev;
@ -114,7 +113,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;
int minor; unsigned int minor;
int err; int err;
if (!d) { if (!d) {
@ -132,12 +131,6 @@ int lirc_register_driver(struct lirc_driver *d)
return -EINVAL; return -EINVAL;
} }
if (d->minor >= MAX_IRCTL_DEVICES) {
dev_err(d->dev, "minor must be between 0 and %d!\n",
MAX_IRCTL_DEVICES - 1);
return -EBADRQC;
}
if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) {
dev_err(d->dev, "code length must be less than %d bits\n", dev_err(d->dev, "code length must be less than %d bits\n",
BUFLEN * 8); BUFLEN * 8);
@ -152,21 +145,14 @@ int lirc_register_driver(struct lirc_driver *d)
mutex_lock(&lirc_dev_lock); mutex_lock(&lirc_dev_lock);
minor = d->minor; /* find first free slot for driver */
for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
if (!irctls[minor])
break;
if (minor < 0) { if (minor == MAX_IRCTL_DEVICES) {
/* find first free slot for driver */ dev_err(d->dev, "no free slots for drivers!\n");
for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) err = -ENOMEM;
if (!irctls[minor])
break;
if (minor == MAX_IRCTL_DEVICES) {
dev_err(d->dev, "no free slots for drivers!\n");
err = -ENOMEM;
goto out_lock;
}
} else if (irctls[minor]) {
dev_err(d->dev, "minor (%d) just registered!\n", minor);
err = -EBUSY;
goto out_lock; goto out_lock;
} }
@ -178,6 +164,7 @@ int lirc_register_driver(struct lirc_driver *d)
mutex_init(&ir->irctl_lock); mutex_init(&ir->irctl_lock);
irctls[minor] = ir; irctls[minor] = ir;
d->irctl = ir;
d->minor = minor; d->minor = minor;
/* some safety check 8-) */ /* some safety check 8-) */
@ -225,7 +212,7 @@ int lirc_register_driver(struct lirc_driver *d)
dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
ir->d.name, ir->d.minor); ir->d.name, ir->d.minor);
return minor; return 0;
out_cdev: out_cdev:
cdev_del(&ir->cdev); cdev_del(&ir->cdev);
@ -238,38 +225,24 @@ int lirc_register_driver(struct lirc_driver *d)
} }
EXPORT_SYMBOL(lirc_register_driver); EXPORT_SYMBOL(lirc_register_driver);
int lirc_unregister_driver(int minor) void lirc_unregister_driver(struct lirc_driver *d)
{ {
struct irctl *ir; struct irctl *ir;
if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { if (!d || !d->irctl)
pr_err("minor (%d) must be between 0 and %d!\n", return;
minor, MAX_IRCTL_DEVICES - 1);
return -EBADRQC;
}
ir = irctls[minor]; ir = d->irctl;
if (!ir) {
pr_err("failed to get irctl\n");
return -ENOENT;
}
mutex_lock(&lirc_dev_lock); mutex_lock(&lirc_dev_lock);
if (ir->d.minor != minor) {
dev_err(ir->d.dev, "lirc_dev: minor %d device not registered\n",
minor);
mutex_unlock(&lirc_dev_lock);
return -ENOENT;
}
dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n",
ir->d.name, ir->d.minor); d->name, d->minor);
ir->attached = 0; ir->attached = 0;
if (ir->open) { if (ir->open) {
dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
ir->d.name, ir->d.minor); d->name, d->minor);
wake_up_interruptible(&ir->buf->wait_poll); wake_up_interruptible(&ir->buf->wait_poll);
} }
@ -278,8 +251,6 @@ int lirc_unregister_driver(int minor)
device_del(&ir->dev); device_del(&ir->dev);
cdev_del(&ir->cdev); cdev_del(&ir->cdev);
put_device(&ir->dev); put_device(&ir->dev);
return 0;
} }
EXPORT_SYMBOL(lirc_unregister_driver); EXPORT_SYMBOL(lirc_unregister_driver);
@ -306,11 +277,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
if (ir->d.minor == NOPLUG) {
retval = -ENODEV;
goto error;
}
if (ir->open) { if (ir->open) {
retval = -EBUSY; retval = -EBUSY;
goto error; goto error;
@ -403,7 +369,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
ir->d.name, ir->d.minor, cmd); ir->d.name, ir->d.minor, cmd);
if (ir->d.minor == NOPLUG || !ir->attached) { if (!ir->attached) {
dev_err(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n", dev_err(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n",
ir->d.name, ir->d.minor); ir->d.name, ir->d.minor);
return -ENODEV; return -ENODEV;

View file

@ -183,10 +183,7 @@ static void release_ir_device(struct kref *ref)
* ir->open_count == 0 - happens on final close() * ir->open_count == 0 - happens on final close()
* ir_lock, tx_ref_lock, rx_ref_lock, all released * ir_lock, tx_ref_lock, rx_ref_lock, all released
*/ */
if (ir->l.minor >= 0) { lirc_unregister_driver(&ir->l);
lirc_unregister_driver(ir->l.minor);
ir->l.minor = -1;
}
if (kfifo_initialized(&ir->rbuf.fifo)) if (kfifo_initialized(&ir->rbuf.fifo))
lirc_buffer_free(&ir->rbuf); lirc_buffer_free(&ir->rbuf);
@ -1385,7 +1382,6 @@ static const struct file_operations lirc_fops = {
static struct lirc_driver lirc_template = { static struct lirc_driver lirc_template = {
.name = "lirc_zilog", .name = "lirc_zilog",
.minor = -1,
.code_length = 13, .code_length = 13,
.buffer_size = BUFLEN / 2, .buffer_size = BUFLEN / 2,
.chunk_size = 2, .chunk_size = 2,
@ -1599,14 +1595,14 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
} }
/* register with lirc */ /* register with lirc */
ir->l.minor = lirc_register_driver(&ir->l); ret = lirc_register_driver(&ir->l);
if (ir->l.minor < 0) { if (ret < 0) {
dev_err(tx->ir->l.dev, dev_err(tx->ir->l.dev,
"%s: lirc_register_driver() failed: %i\n", "%s: lirc_register_driver() failed: %i\n",
__func__, ir->l.minor); __func__, ret);
ret = -EBADRQC;
goto out_put_xx; goto out_put_xx;
} }
dev_info(ir->l.dev, dev_info(ir->l.dev,
"IR unit on %s (i2c-%d) registered as lirc%d and ready\n", "IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
adap->name, adap->nr, ir->l.minor); adap->name, adap->nr, ir->l.minor);

View file

@ -116,10 +116,8 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
* *
* @name: this string will be used for logs * @name: this string will be used for logs
* *
* @minor: indicates minor device (/dev/lirc) number for * @minor: the minor device (/dev/lircX) number for a registered
* registered driver if caller fills it with negative * driver.
* value, then the first free minor number will be used
* (if available).
* *
* @code_length: length of the remote control key code expressed in bits. * @code_length: length of the remote control key code expressed in bits.
* *
@ -157,10 +155,12 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
* device. * device.
* *
* @owner: the module owning this struct * @owner: the module owning this struct
*
* @irctl: the struct irctl for this LIRC device.
*/ */
struct lirc_driver { struct lirc_driver {
char name[40]; char name[40];
int minor; unsigned int minor;
__u32 code_length; __u32 code_length;
unsigned int buffer_size; /* in chunks holding one code each */ unsigned int buffer_size; /* in chunks holding one code each */
__u32 features; __u32 features;
@ -175,19 +175,17 @@ struct lirc_driver {
const struct file_operations *fops; const struct file_operations *fops;
struct device *dev; struct device *dev;
struct module *owner; struct module *owner;
struct irctl *irctl;
}; };
/* following functions can be called ONLY from user context /* following functions can be called ONLY from user context
* *
* returns negative value on error or minor number * returns negative value on error or zero
* of the registered device if success
* contents of the structure pointed by p is copied * contents of the structure pointed by p is copied
*/ */
extern int lirc_register_driver(struct lirc_driver *d); int lirc_register_driver(struct lirc_driver *d);
/* returns negative value on error or 0 if success void lirc_unregister_driver(struct lirc_driver *d);
*/
extern int lirc_unregister_driver(int minor);
/* Returns the private data stored in the lirc_driver /* Returns the private data stored in the lirc_driver
* associated with the given device file pointer. * associated with the given device file pointer.