[media] soc_camera: remove V4L2_FL_LOCK_ALL_FOPS

Add proper locking to the file operations, allowing for the removal
of the V4L2_FL_LOCK_ALL_FOPS flag.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b03ffec..9758217 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -507,9 +507,12 @@
 
 	ici = to_soc_camera_host(icd->parent);
 
+	if (mutex_lock_interruptible(&icd->video_lock))
+		return -ERESTARTSYS;
 	if (!try_module_get(ici->ops->owner)) {
 		dev_err(icd->pdev, "Couldn't lock capture bus driver.\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto emodule;
 	}
 
 	icd->use_count++;
@@ -570,6 +573,7 @@
 		}
 		v4l2_ctrl_handler_setup(&icd->ctrl_handler);
 	}
+	mutex_unlock(&icd->video_lock);
 
 	file->private_data = icd;
 	dev_dbg(icd->pdev, "camera device open\n");
@@ -590,6 +594,8 @@
 eiciadd:
 	icd->use_count--;
 	module_put(ici->ops->owner);
+emodule:
+	mutex_unlock(&icd->video_lock);
 
 	return ret;
 }
@@ -599,6 +605,7 @@
 	struct soc_camera_device *icd = file->private_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 
+	mutex_lock(&icd->video_lock);
 	icd->use_count--;
 	if (!icd->use_count) {
 		struct soc_camera_link *icl = to_soc_camera_link(icd);
@@ -615,6 +622,7 @@
 
 	if (icd->streamer == file)
 		icd->streamer = NULL;
+	mutex_unlock(&icd->video_lock);
 
 	module_put(ici->ops->owner);
 
@@ -645,10 +653,13 @@
 	if (icd->streamer != file)
 		return -EBUSY;
 
+	if (mutex_lock_interruptible(&icd->video_lock))
+		return -ERESTARTSYS;
 	if (ici->ops->init_videobuf)
 		err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
 	else
 		err = vb2_mmap(&icd->vb2_vidq, vma);
+	mutex_unlock(&icd->video_lock);
 
 	dev_dbg(icd->pdev, "vma start=0x%08lx, size=%ld, ret=%d\n",
 		(unsigned long)vma->vm_start,
@@ -662,16 +673,18 @@
 {
 	struct soc_camera_device *icd = file->private_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	unsigned res = POLLERR;
 
 	if (icd->streamer != file)
-		return -EBUSY;
-
-	if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
-		dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
 		return POLLERR;
-	}
 
-	return ici->ops->poll(file, pt);
+	mutex_lock(&icd->video_lock);
+	if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream))
+		dev_err(icd->pdev, "Trying to poll with no queued buffers!\n");
+	else
+		res = ici->ops->poll(file, pt);
+	mutex_unlock(&icd->video_lock);
+	return res;
 }
 
 void soc_camera_lock(struct vb2_queue *vq)
@@ -1432,10 +1445,6 @@
 	vdev->tvnorms		= V4L2_STD_UNKNOWN;
 	vdev->ctrl_handler	= &icd->ctrl_handler;
 	vdev->lock		= &icd->video_lock;
-	/* Locking in file operations other than ioctl should be done
-	   by the driver, not the V4L2 core.
-	   This driver needs auditing so that this flag can be removed. */
-	set_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags);
 
 	icd->vdev = vdev;