au0828: Fix dev_state handling
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 22 Mar 2016 12:21:57 +0000 (09:21 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Apr 2016 06:42:09 +0000 (15:42 +0900)
commit e8e3039f5b941f7825d335f8ca11c12a8104db11 upstream.

The au0828 dev_state is actually a bit mask. It should not be
checking with "==" but, instead, with a logic and. There are some
places where it was doing it wrong.

Fix that by replacing the dev_state set/clear/test with the
bitops.

As reviewed by Shuah:
"Looks good. Tested running bind/unbind au0828 loop for 1000 times.
Didn't see any problems and the v4l2_querycap() problem has been
fixed with this patch.

After the above test, ran bind/unbind snd_usb_audio 1000 times.
Didn't see any problems. Generated media graph and the graph
looks good."

Reviewed-by: Shuah Khan <shuahkh@osg.samsung.com>
Tested-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/media/usb/au0828/au0828-core.c
drivers/media/usb/au0828/au0828-input.c
drivers/media/usb/au0828/au0828-video.c
drivers/media/usb/au0828/au0828.h

index 0934024fb89d37b00ca01233a59bf76e4ec7acab..d91ded795c93b9da8e0fcf00fcd20ae723df621e 100644 (file)
@@ -159,7 +159,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
           Set the status so poll routines can check and avoid
           access after disconnect.
        */
-       dev->dev_state = DEV_DISCONNECTED;
+       set_bit(DEV_DISCONNECTED, &dev->dev_state);
 
        au0828_rc_unregister(dev);
        /* Digital TV */
index b0f0679719798c4b8212b9dabee3f992b018c17a..3d6687f0407dfe4c301ca2e9f4bca594c9201522 100644 (file)
@@ -130,7 +130,7 @@ static int au0828_get_key_au8522(struct au0828_rc *ir)
        bool first = true;
 
        /* do nothing if device is disconnected */
-       if (ir->dev->dev_state == DEV_DISCONNECTED)
+       if (test_bit(DEV_DISCONNECTED, &ir->dev->dev_state))
                return 0;
 
        /* Check IR int */
@@ -260,7 +260,7 @@ static void au0828_rc_stop(struct rc_dev *rc)
        cancel_delayed_work_sync(&ir->work);
 
        /* do nothing if device is disconnected */
-       if (ir->dev->dev_state != DEV_DISCONNECTED) {
+       if (!test_bit(DEV_DISCONNECTED, &ir->dev->dev_state)) {
                /* Disable IR */
                au8522_rc_clear(ir, 0xe0, 1 << 4);
        }
index 36fde46ea2cf9a65a0cbd9c8b052199965eb23b0..7b2fe1b56039e5edd78b9a5ec55fd7a0cb42ec79 100644 (file)
@@ -104,14 +104,13 @@ static inline void print_err_status(struct au0828_dev *dev,
 
 static int check_dev(struct au0828_dev *dev)
 {
-       if (dev->dev_state & DEV_DISCONNECTED) {
+       if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) {
                pr_info("v4l2 ioctl: device not present\n");
                return -ENODEV;
        }
 
-       if (dev->dev_state & DEV_MISCONFIGURED) {
-               pr_info("v4l2 ioctl: device is misconfigured; "
-                      "close and open it again\n");
+       if (test_bit(DEV_MISCONFIGURED, &dev->dev_state)) {
+               pr_info("v4l2 ioctl: device is misconfigured; close and open it again\n");
                return -EIO;
        }
        return 0;
@@ -519,8 +518,8 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
        if (!dev)
                return 0;
 
-       if ((dev->dev_state & DEV_DISCONNECTED) ||
-           (dev->dev_state & DEV_MISCONFIGURED))
+       if (test_bit(DEV_DISCONNECTED, &dev->dev_state) ||
+           test_bit(DEV_MISCONFIGURED, &dev->dev_state))
                return 0;
 
        if (urb->status < 0) {
@@ -766,10 +765,10 @@ static int au0828_stream_interrupt(struct au0828_dev *dev)
        int ret = 0;
 
        dev->stream_state = STREAM_INTERRUPT;
-       if (dev->dev_state == DEV_DISCONNECTED)
+       if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
                return -ENODEV;
        else if (ret) {
-               dev->dev_state = DEV_MISCONFIGURED;
+               set_bit(DEV_MISCONFIGURED, &dev->dev_state);
                dprintk(1, "%s device is misconfigured!\n", __func__);
                return ret;
        }
@@ -958,7 +957,7 @@ static int au0828_v4l2_open(struct file *filp)
        int ret;
 
        dprintk(1,
-               "%s called std_set %d dev_state %d stream users %d users %d\n",
+               "%s called std_set %d dev_state %ld stream users %d users %d\n",
                __func__, dev->std_set_in_tuner_core, dev->dev_state,
                dev->streaming_users, dev->users);
 
@@ -977,7 +976,7 @@ static int au0828_v4l2_open(struct file *filp)
                au0828_analog_stream_enable(dev);
                au0828_analog_stream_reset(dev);
                dev->stream_state = STREAM_OFF;
-               dev->dev_state |= DEV_INITIALIZED;
+               set_bit(DEV_INITIALIZED, &dev->dev_state);
        }
        dev->users++;
        mutex_unlock(&dev->lock);
@@ -991,7 +990,7 @@ static int au0828_v4l2_close(struct file *filp)
        struct video_device *vdev = video_devdata(filp);
 
        dprintk(1,
-               "%s called std_set %d dev_state %d stream users %d users %d\n",
+               "%s called std_set %d dev_state %ld stream users %d users %d\n",
                __func__, dev->std_set_in_tuner_core, dev->dev_state,
                dev->streaming_users, dev->users);
 
@@ -1007,7 +1006,7 @@ static int au0828_v4l2_close(struct file *filp)
                del_timer_sync(&dev->vbi_timeout);
        }
 
-       if (dev->dev_state & DEV_DISCONNECTED)
+       if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
                goto end;
 
        if (dev->users == 1) {
@@ -1036,7 +1035,7 @@ static void au0828_init_tuner(struct au0828_dev *dev)
                .type = V4L2_TUNER_ANALOG_TV,
        };
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        if (dev->std_set_in_tuner_core)
@@ -1108,7 +1107,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
        struct video_device *vdev = video_devdata(file);
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        strlcpy(cap->driver, "au0828", sizeof(cap->driver));
@@ -1151,7 +1150,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        f->fmt.pix.width = dev->width;
@@ -1170,7 +1169,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
@@ -1182,7 +1181,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        struct au0828_dev *dev = video_drvdata(file);
        int rc;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        rc = check_dev(dev);
@@ -1204,7 +1203,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        if (norm == dev->std)
@@ -1236,7 +1235,7 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        *norm = dev->std;
@@ -1259,7 +1258,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
                [AU0828_VMUX_DEBUG] = "tv debug"
        };
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        tmp = input->index;
@@ -1289,7 +1288,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        *i = dev->ctrl_input;
@@ -1300,7 +1299,7 @@ static void au0828_s_input(struct au0828_dev *dev, int index)
 {
        int i;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        switch (AUVI_INPUT(index).type) {
@@ -1385,7 +1384,7 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        a->index = dev->ctrl_ainput;
@@ -1405,7 +1404,7 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio
        if (a->index != dev->ctrl_ainput)
                return -EINVAL;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
        return 0;
 }
@@ -1417,7 +1416,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
        if (t->index != 0)
                return -EINVAL;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        strcpy(t->name, "Auvitek tuner");
@@ -1437,7 +1436,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
        if (t->index != 0)
                return -EINVAL;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        au0828_init_tuner(dev);
@@ -1459,7 +1458,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 
        if (freq->tuner != 0)
                return -EINVAL;
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
        freq->frequency = dev->ctrl_freq;
        return 0;
@@ -1474,7 +1473,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
        if (freq->tuner != 0)
                return -EINVAL;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        au0828_init_tuner(dev);
@@ -1500,7 +1499,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        format->fmt.vbi.samples_per_line = dev->vbi_width;
@@ -1526,7 +1525,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
        if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        cc->bounds.left = 0;
@@ -1548,7 +1547,7 @@ static int vidioc_g_register(struct file *file, void *priv,
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        reg->val = au0828_read(dev, reg->reg);
@@ -1561,7 +1560,7 @@ static int vidioc_s_register(struct file *file, void *priv,
 {
        struct au0828_dev *dev = video_drvdata(file);
 
-       dprintk(1, "%s called std_set %d dev_state %d\n", __func__,
+       dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
                dev->std_set_in_tuner_core, dev->dev_state);
 
        return au0828_writereg(dev, reg->reg, reg->val);
index 60b59391ea2ae48eee40cd124ade5c4ea50ca309..d1b6405a05a44648c3dca2ad733c5552d0001c52 100644 (file)
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bitops.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -122,9 +123,9 @@ enum au0828_stream_state {
 
 /* device state */
 enum au0828_dev_state {
-       DEV_INITIALIZED = 0x01,
-       DEV_DISCONNECTED = 0x02,
-       DEV_MISCONFIGURED = 0x04
+       DEV_INITIALIZED = 0,
+       DEV_DISCONNECTED = 1,
+       DEV_MISCONFIGURED = 2
 };
 
 struct au0828_dev;
@@ -248,7 +249,7 @@ struct au0828_dev {
        int input_type;
        int std_set_in_tuner_core;
        unsigned int ctrl_input;
-       enum au0828_dev_state dev_state;
+       long unsigned int dev_state; /* defined at enum au0828_dev_state */;
        enum au0828_stream_state stream_state;
        wait_queue_head_t open;