snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
dev->driver_name);
- drv->minor = -1;
drv->features = features;
drv->data = &dev->raw->lirc;
drv->rbuf = NULL;
drv->rdev = dev;
drv->owner = THIS_MODULE;
- drv->minor = lirc_register_driver(drv);
- if (drv->minor < 0) {
- rc = -ENODEV;
+ rc = lirc_register_driver(drv);
+ if (rc < 0)
goto out;
- }
dev->raw->lirc.drv = drv;
dev->raw->lirc.dev = dev;
{
struct lirc_codec *lirc = &dev->raw->lirc;
- lirc_unregister_driver(lirc->drv->minor);
+ lirc_unregister_driver(lirc->drv);
kfree(lirc->drv);
lirc->drv = NULL;
#include <media/lirc.h>
#include <media/lirc_dev.h>
-#define NOPLUG -1
#define LOGHEAD "lirc_dev (%s[%d]): "
static dev_t lirc_base_dev;
int lirc_register_driver(struct lirc_driver *d)
{
struct irctl *ir;
- int minor;
+ unsigned int minor;
int err;
if (!d) {
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)) {
dev_err(d->dev, "code length must be less than %d bits\n",
BUFLEN * 8);
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) {
- /* 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");
- err = -ENOMEM;
- goto out_lock;
- }
- } else if (irctls[minor]) {
- dev_err(d->dev, "minor (%d) just registered!\n", minor);
- err = -EBUSY;
+ if (minor == MAX_IRCTL_DEVICES) {
+ dev_err(d->dev, "no free slots for drivers!\n");
+ err = -ENOMEM;
goto out_lock;
}
mutex_init(&ir->irctl_lock);
irctls[minor] = ir;
+ d->irctl = ir;
d->minor = minor;
/* some safety check 8-) */
dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
ir->d.name, ir->d.minor);
- return minor;
+ return 0;
out_cdev:
cdev_del(&ir->cdev);
}
EXPORT_SYMBOL(lirc_register_driver);
-int lirc_unregister_driver(int minor)
+void lirc_unregister_driver(struct lirc_driver *d)
{
struct irctl *ir;
- if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
- pr_err("minor (%d) must be between 0 and %d!\n",
- minor, MAX_IRCTL_DEVICES - 1);
- return -EBADRQC;
- }
+ if (!d || !d->irctl)
+ return;
- ir = irctls[minor];
- if (!ir) {
- pr_err("failed to get irctl\n");
- return -ENOENT;
- }
+ ir = d->irctl;
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",
- ir->d.name, ir->d.minor);
+ d->name, d->minor);
ir->attached = 0;
if (ir->open) {
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);
}
device_del(&ir->dev);
cdev_del(&ir->cdev);
put_device(&ir->dev);
-
- return 0;
}
EXPORT_SYMBOL(lirc_unregister_driver);
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) {
retval = -EBUSY;
goto error;
dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
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",
ir->d.name, ir->d.minor);
return -ENODEV;
* ir->open_count == 0 - happens on final close()
* ir_lock, tx_ref_lock, rx_ref_lock, all released
*/
- if (ir->l.minor >= 0) {
- lirc_unregister_driver(ir->l.minor);
- ir->l.minor = -1;
- }
+ lirc_unregister_driver(&ir->l);
if (kfifo_initialized(&ir->rbuf.fifo))
lirc_buffer_free(&ir->rbuf);
static struct lirc_driver lirc_template = {
.name = "lirc_zilog",
- .minor = -1,
.code_length = 13,
.buffer_size = BUFLEN / 2,
.chunk_size = 2,
}
/* register with lirc */
- ir->l.minor = lirc_register_driver(&ir->l);
- if (ir->l.minor < 0) {
+ ret = lirc_register_driver(&ir->l);
+ if (ret < 0) {
dev_err(tx->ir->l.dev,
"%s: lirc_register_driver() failed: %i\n",
- __func__, ir->l.minor);
- ret = -EBADRQC;
+ __func__, ret);
goto out_put_xx;
}
+
dev_info(ir->l.dev,
"IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
adap->name, adap->nr, ir->l.minor);
*
* @name: this string will be used for logs
*
- * @minor: indicates minor device (/dev/lirc) number for
- * registered driver if caller fills it with negative
- * value, then the first free minor number will be used
- * (if available).
+ * @minor: the minor device (/dev/lircX) number for a registered
+ * driver.
*
* @code_length: length of the remote control key code expressed in bits.
*
* device.
*
* @owner: the module owning this struct
+ *
+ * @irctl: the struct irctl for this LIRC device.
*/
struct lirc_driver {
char name[40];
- int minor;
+ unsigned int minor;
__u32 code_length;
unsigned int buffer_size; /* in chunks holding one code each */
__u32 features;
const struct file_operations *fops;
struct device *dev;
struct module *owner;
+ struct irctl *irctl;
};
/* following functions can be called ONLY from user context
*
- * returns negative value on error or minor number
- * of the registered device if success
+ * returns negative value on error or zero
* 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
-*/
-extern int lirc_unregister_driver(int minor);
+void lirc_unregister_driver(struct lirc_driver *d);
/* Returns the private data stored in the lirc_driver
* associated with the given device file pointer.