[media] stk-webcam: enable core-locking
authorHans Verkuil <hans.verkuil@cisco.com>
Mon, 4 Feb 2013 12:27:32 +0000 (09:27 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 5 Mar 2013 17:43:10 +0000 (14:43 -0300)
This makes it possible to switch to unlocked_ioctl.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Tested-by: Arvydas Sidorenko <asido4@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/usb/stkwebcam/stk-webcam.c
drivers/media/usb/stkwebcam/stk-webcam.h

index bb52457..2f1a09d 100644 (file)
@@ -610,6 +610,8 @@ static int v4l_stk_open(struct file *fp)
        if (dev == NULL || !is_present(dev))
                return -ENXIO;
 
+       if (mutex_lock_interruptible(&dev->lock))
+               return -ERESTARTSYS;
        if (!dev->first_init)
                stk_camera_write_reg(dev, 0x0, 0x24);
        else
@@ -618,6 +620,7 @@ static int v4l_stk_open(struct file *fp)
        err = v4l2_fh_open(fp);
        if (!err)
                usb_autopm_get_interface(dev->interface);
+       mutex_unlock(&dev->lock);
        return err;
 }
 
@@ -625,6 +628,7 @@ static int v4l_stk_release(struct file *fp)
 {
        struct stk_camera *dev = video_drvdata(fp);
 
+       mutex_lock(&dev->lock);
        if (dev->owner == fp) {
                stk_stop_stream(dev);
                stk_free_buffers(dev);
@@ -635,10 +639,11 @@ static int v4l_stk_release(struct file *fp)
 
        if (is_present(dev))
                usb_autopm_put_interface(dev->interface);
+       mutex_unlock(&dev->lock);
        return v4l2_fh_release(fp);
 }
 
-static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
+static ssize_t stk_read(struct file *fp, char __user *buf,
                size_t count, loff_t *f_pos)
 {
        int i;
@@ -699,6 +704,19 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
        return count;
 }
 
+static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
+               size_t count, loff_t *f_pos)
+{
+       struct stk_camera *dev = video_drvdata(fp);
+       int ret;
+
+       if (mutex_lock_interruptible(&dev->lock))
+               return -ERESTARTSYS;
+       ret = stk_read(fp, buf, count, f_pos);
+       mutex_unlock(&dev->lock);
+       return ret;
+}
+
 static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
 {
        struct stk_camera *dev = video_drvdata(fp);
@@ -1183,7 +1201,7 @@ static struct v4l2_file_operations v4l_stk_fops = {
        .read = v4l_stk_read,
        .poll = v4l_stk_poll,
        .mmap = v4l_stk_mmap,
-       .ioctl = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
@@ -1231,6 +1249,7 @@ static int stk_register_video_device(struct stk_camera *dev)
        int err;
 
        dev->vdev = stk_v4l_data;
+       dev->vdev.lock = &dev->lock;
        dev->vdev.debug = debug;
        dev->vdev.v4l2_dev = &dev->v4l2_dev;
        set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags);
@@ -1286,6 +1305,7 @@ static int stk_camera_probe(struct usb_interface *interface,
        dev->v4l2_dev.ctrl_handler = hdl;
 
        spin_lock_init(&dev->spinlock);
+       mutex_init(&dev->lock);
        init_waitqueue_head(&dev->wait_frame);
        dev->first_init = 1; /* webcam LED management */
 
index 2156320..03550cf 100644 (file)
@@ -99,6 +99,7 @@ struct stk_camera {
        struct usb_interface *interface;
        int webcam_model;
        struct file *owner;
+       struct mutex lock;
        int first_init;
 
        u8 isoc_ep;