media: lirc: move lirc_dev->attached to rc_dev->registered
authorSean Young <sean@mess.org>
Tue, 26 Sep 2017 11:31:29 +0000 (07:31 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Thu, 14 Dec 2017 15:35:18 +0000 (10:35 -0500)
This is done to further remove the lirc kernel api. Ensure that every
fops checks for this.

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/rc/ir-lirc-codec.c
drivers/media/rc/lirc_dev.c
drivers/media/rc/rc-main.c
include/media/lirc_dev.h
include/media/rc-core.h

index 2fa1f905a266dfb21a382d2f2c959dcdc1f4db4c..ff74a5d7a0f34cbd8702dd1e3da2c213c6f58c94 100644 (file)
@@ -101,6 +101,9 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
        unsigned int duration = 0; /* signal duration in us */
        int i;
 
+       if (!dev->registered)
+               return -ENODEV;
+
        start = ktime_get();
 
        if (!dev->tx_ir) {
@@ -224,6 +227,9 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
                        return ret;
        }
 
+       if (!dev->registered)
+               return -ENODEV;
+
        switch (cmd) {
        case LIRC_GET_FEATURES:
                if (dev->driver_type == RC_DRIVER_IR_RAW) {
@@ -406,12 +412,11 @@ static unsigned int ir_lirc_poll(struct file *file,
                                 struct poll_table_struct *wait)
 {
        struct rc_dev *rcdev = file->private_data;
-       struct lirc_dev *d = rcdev->lirc_dev;
        unsigned int events = 0;
 
        poll_wait(file, &rcdev->wait_poll, wait);
 
-       if (!d->attached)
+       if (!rcdev->registered)
                events = POLLHUP | POLLERR;
        else if (rcdev->driver_type == RC_DRIVER_IR_RAW &&
                 !kfifo_is_empty(&rcdev->rawir))
@@ -424,7 +429,6 @@ static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
                            size_t length, loff_t *ppos)
 {
        struct rc_dev *rcdev = file->private_data;
-       struct lirc_dev *d = rcdev->lirc_dev;
        unsigned int copied;
        int ret;
 
@@ -434,7 +438,7 @@ static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
        if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
                return -EINVAL;
 
-       if (!d->attached)
+       if (!rcdev->registered)
                return -ENODEV;
 
        do {
@@ -444,12 +448,12 @@ static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
 
                        ret = wait_event_interruptible(rcdev->wait_poll,
                                        !kfifo_is_empty(&rcdev->rawir) ||
-                                       !d->attached);
+                                       !rcdev->registered);
                        if (ret)
                                return ret;
                }
 
-               if (!d->attached)
+               if (!rcdev->registered)
                        return -ENODEV;
 
                ret = mutex_lock_interruptible(&rcdev->lock);
index 9a0ad8d9a0cbca2a7a51a2dfe77203070b774cb3..22171267aa901baef1c8139adbd1e0f98b63ff11 100644 (file)
@@ -122,7 +122,6 @@ int lirc_register_device(struct lirc_dev *d)
 
        cdev_init(&d->cdev, d->fops);
        d->cdev.owner = d->owner;
-       d->attached = true;
 
        err = cdev_device_add(&d->cdev, &d->dev);
        if (err) {
@@ -153,7 +152,6 @@ void lirc_unregister_device(struct lirc_dev *d)
 
        mutex_lock(&d->mutex);
 
-       d->attached = false;
        if (d->open) {
                dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
                        d->name, d->minor);
@@ -180,7 +178,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file)
        if (retval)
                return retval;
 
-       if (!d->attached) {
+       if (!rcdev->registered) {
                retval = -ENODEV;
                goto out;
        }
index e944d28b96d2b329a04338f86053e6c93461490f..8b1b20e7a3c3156e373ec5fba9bfdb9ac2979df2 100644 (file)
@@ -1809,6 +1809,8 @@ int rc_register_device(struct rc_dev *dev)
                        goto out_lirc;
        }
 
+       dev->registered = true;
+
        IR_dprintk(1, "Registered rc%u (driver: %s)\n",
                   dev->minor,
                   dev->driver_name ? dev->driver_name : "unknown");
@@ -1871,6 +1873,14 @@ void rc_unregister_device(struct rc_dev *dev)
 
        rc_free_rx_device(dev);
 
+       mutex_lock(&dev->lock);
+       dev->registered = false;
+       mutex_unlock(&dev->lock);
+
+       /*
+        * lirc device should be freed with dev->registered = false, so
+        * that userspace polling will get notified.
+        */
        if (dev->driver_type != RC_DRIVER_SCANCODE)
                ir_lirc_unregister(dev);
 
index 14d3eb36672e30b514ff3471078962f12112b22f..5782add67eddae7838161ad88f798c48a8552158 100644 (file)
@@ -26,7 +26,6 @@
  * @rdev:              &struct rc_dev associated with the device
  * @fops:              &struct file_operations for the device
  * @owner:             the module owning this struct
- * @attached:          if the device is still live
  * @open:              open count for the device's chardev
  * @mutex:             serialises file_operations calls
  * @dev:               &struct device assigned to the device
@@ -40,7 +39,6 @@ struct lirc_dev {
        const struct file_operations *fops;
        struct module *owner;
 
-       bool attached;
        int open;
 
        struct mutex mutex; /* protect from simultaneous accesses */
index fb91666bf88159dcc448984f82528b74875ee257..b6d719734744cb55b601511a5039f35a41ed6b81 100644 (file)
@@ -127,6 +127,8 @@ enum rc_filter_type {
  * @wait_poll: poll struct for lirc device
  * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or
  *     LIRC_MODE_PULSE
+ * @registered: set to true by rc_register_device(), false by
+ *     rc_unregister_device
  * @change_protocol: allow changing the protocol used on hardware decoders
  * @open: callback to allow drivers to enable polling/irq when IR input device
  *     is opened.
@@ -197,6 +199,7 @@ struct rc_dev {
        wait_queue_head_t               wait_poll;
        u8                              send_mode;
 #endif
+       bool                            registered;
        int                             (*change_protocol)(struct rc_dev *dev, u64 *rc_proto);
        int                             (*open)(struct rc_dev *dev);
        void                            (*close)(struct rc_dev *dev);