V4L/DVB (8780): v4l: replace the last uses of video_exclusive_open/release

Handle the video_exclusive_open/release functionality inside the
driver.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 9e436ad..0d4f9b6 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -116,6 +116,7 @@
 	int width, height;
 	int frame_bytes, line_bytes;
 	wait_queue_head_t wait;
+	unsigned long in_use;
 	struct mutex lock;
 };
 
@@ -742,10 +743,23 @@
  * Video4Linux Module functions
  *
  ****************************************************************************/
+static struct ar_device ardev;
+
+static int ar_exclusive_open(struct inode *inode, struct file *file)
+{
+	return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
+}
+
+static int ar_exclusive_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &ardev.in_use);
+	return 0;
+}
+
 static const struct file_operations ar_fops = {
 	.owner		= THIS_MODULE,
-	.open		= video_exclusive_open,
-	.release	= video_exclusive_release,
+	.open		= ar_exclusive_open,
+	.release	= ar_exclusive_release,
 	.read		= ar_read,
 	.ioctl		= ar_ioctl,
 #ifdef CONFIG_COMPAT
@@ -762,7 +776,6 @@
 };
 
 #define ALIGN4(x)	((((int)(x)) & 0x3) == 0)
-static struct ar_device ardev;
 
 static int __init ar_init(void)
 {
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 01f0770..e8e1bb1 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -894,10 +894,27 @@
 	return len;
 }
 
+static int qcam_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct video_device *dev = video_devdata(file);
+	struct qcam_device *qcam = (struct qcam_device *)dev;
+
+	return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
+}
+
+static int qcam_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct video_device *dev = video_devdata(file);
+	struct qcam_device *qcam = (struct qcam_device *)dev;
+
+	clear_bit(0, &qcam->in_use);
+	return 0;
+}
+
 static const struct file_operations qcam_fops = {
 	.owner		= THIS_MODULE,
-	.open           = video_exclusive_open,
-	.release        = video_exclusive_release,
+	.open           = qcam_exclusive_open,
+	.release        = qcam_exclusive_release,
 	.ioctl          = qcam_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= v4l_compat_ioctl32,
diff --git a/drivers/media/video/bw-qcam.h b/drivers/media/video/bw-qcam.h
index 6701daf..8a60c5d 100644
--- a/drivers/media/video/bw-qcam.h
+++ b/drivers/media/video/bw-qcam.h
@@ -65,4 +65,5 @@
 	int top, left;
 	int status;
 	unsigned int saved_bits;
+	unsigned long in_use;
 };
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 7f6c6b4..2196c1d 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -51,6 +51,7 @@
 	int contrast, brightness, whitebal;
 	int top, left;
 	unsigned int bidirectional;
+	unsigned long in_use;
 	struct mutex lock;
 };
 
@@ -687,11 +688,28 @@
 	return len;
 }
 
+static int qcam_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct video_device *dev = video_devdata(file);
+	struct qcam_device *qcam = (struct qcam_device *)dev;
+
+	return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
+}
+
+static int qcam_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct video_device *dev = video_devdata(file);
+	struct qcam_device *qcam = (struct qcam_device *)dev;
+
+	clear_bit(0, &qcam->in_use);
+	return 0;
+}
+
 /* video device template */
 static const struct file_operations qcam_fops = {
 	.owner		= THIS_MODULE,
-	.open           = video_exclusive_open,
-	.release        = video_exclusive_release,
+	.open           = qcam_exclusive_open,
+	.release        = qcam_exclusive_release,
 	.ioctl          = qcam_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= v4l_compat_ioctl32,
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 102a5b9..6418f4a 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -843,21 +843,16 @@
 
 static int meye_open(struct inode *inode, struct file *file)
 {
-	int i, err;
+	int i;
 
-	lock_kernel();
-	err = video_exclusive_open(inode, file);
-	if (err < 0) {
-		unlock_kernel();
-		return err;
-	}
+	if (test_and_set_bit(0, &meye.in_use))
+		return -EBUSY;
 
 	mchip_hic_stop();
 
 	if (mchip_dma_alloc()) {
 		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
-		video_exclusive_release(inode, file);
-		unlock_kernel();
+		clear_bit(0, &meye.in_use);
 		return -ENOBUFS;
 	}
 
@@ -865,7 +860,6 @@
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
 	kfifo_reset(meye.grabq);
 	kfifo_reset(meye.doneq);
-	unlock_kernel();
 	return 0;
 }
 
@@ -873,7 +867,7 @@
 {
 	mchip_hic_stop();
 	mchip_dma_free();
-	video_exclusive_release(inode, file);
+	clear_bit(0, &meye.in_use);
 	return 0;
 }
 
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
index d535748..5f70a10 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/video/meye.h
@@ -311,6 +311,7 @@
 	struct video_device *video_dev;	/* video device parameters */
 	struct video_picture picture;	/* video picture parameters */
 	struct meye_params params;	/* additional parameters */
+	unsigned long in_use;		/* set to 1 if the device is in use */
 #ifdef CONFIG_PM
 	u8 pm_mchip_mode;		/* old mchip mode */
 #endif
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 7c84f79..b39794f 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -47,6 +47,7 @@
 	struct video_picture picture;
 	int height;
 	int width;
+	unsigned long in_use;
 	struct mutex lock;
 };
 
@@ -881,10 +882,27 @@
 	return len;
 }
 
+static int pms_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct video_device *v = video_devdata(file);
+	struct pms_device *pd = (struct pms_device *)v;
+
+	return test_and_set_bit(0, &pd->in_use) ? -EBUSY : 0;
+}
+
+static int pms_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct video_device *v = video_devdata(file);
+	struct pms_device *pd = (struct pms_device *)v;
+
+	clear_bit(0, &pd->in_use);
+	return 0;
+}
+
 static const struct file_operations pms_fops = {
 	.owner		= THIS_MODULE,
-	.open           = video_exclusive_open,
-	.release        = video_exclusive_release,
+	.open           = pms_exclusive_open,
+	.release        = pms_exclusive_release,
 	.ioctl          = pms_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= v4l_compat_ioctl32,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e2c538e..5f5aa20 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -61,6 +61,7 @@
 	u8     pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
 	int    is_searching[NUM_DAUS];
 	struct i2c_client *client;
+	unsigned long in_use;
 	struct mutex lock;
 };
 
@@ -736,22 +737,14 @@
 {
 	struct video_device *vd = video_devdata(file);
 	struct saa5246a_device *t = vd->priv;
-	int err;
 
-	lock_kernel();
-	err = video_exclusive_open(inode,file);
-	if (err < 0) {
-		unlock_kernel();
-		return err;
-	}
+	if (t->client == NULL)
+		return -ENODEV;
 
-	if (t->client==NULL) {
-		err = -ENODEV;
-		goto fail;
-	}
+	if (test_and_set_bit(0, &t->in_use))
+		return -EBUSY;
 
 	if (i2c_senddata(t, SAA5246A_REGISTER_R0,
-
 		R0_SELECT_R11 |
 		R0_PLL_TIME_CONSTANT_LONG |
 		R0_ENABLE_nODD_EVEN_OUTPUT |
@@ -777,17 +770,10 @@
 
 		COMMAND_END))
 	{
-		err = -EIO;
-		goto fail;
+		clear_bit(0, &t->in_use);
+		return -EIO;
 	}
-	unlock_kernel();
-
 	return 0;
-
-fail:
-	video_exclusive_release(inode,file);
-	unlock_kernel();
-	return err;
 }
 
 static int saa5246a_release(struct inode *inode, struct file *file)
@@ -806,7 +792,7 @@
 		R1_VCS_TO_SCS,
 
 		COMMAND_END);
-	video_exclusive_release(inode,file);
+	clear_bit(0, &t->in_use);
 	return 0;
 }
 
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 96c0fdf..dfd8a93 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -110,6 +110,7 @@
 	int disp_mode;
 	int virtual_mode;
 	struct i2c_client *client;
+	unsigned long in_use;
 	struct mutex lock;
 };
 
@@ -631,34 +632,27 @@
 static int saa5249_open(struct inode *inode, struct file *file)
 {
 	struct video_device *vd = video_devdata(file);
-	struct saa5249_device *t=vd->priv;
-	int err,pgbuf;
+	struct saa5249_device *t = vd->priv;
+	int pgbuf;
 
-	lock_kernel();
-	err = video_exclusive_open(inode,file);
-	if (err < 0) {
-		unlock_kernel();
-		return err;
-	}
+	if (t->client == NULL)
+		return -ENODEV;
 
-	if (t->client==NULL) {
-		err = -ENODEV;
-		goto fail;
-	}
+	if (test_and_set_bit(0, &t->in_use))
+		return -EBUSY;
 
-	if (i2c_senddata(t, 0, 0, -1) ||		/* Select R11 */
-						/* Turn off parity checks (we do this ourselves) */
+	if (i2c_senddata(t, 0, 0, -1) || /* Select R11 */
+		/* Turn off parity checks (we do this ourselves) */
 		i2c_senddata(t, 1, disp_modes[t->disp_mode][0], 0, -1) ||
-						/* Display TV-picture, no virtual rows */
-		i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1)) /* Set display to page 4 */
-
+		/* Display TV-picture, no virtual rows */
+		i2c_senddata(t, 4, NUM_DAUS, disp_modes[t->disp_mode][1], disp_modes[t->disp_mode][2], 7, -1))
+		/* Set display to page 4 */
 	{
-		err = -EIO;
-		goto fail;
+		clear_bit(0, &t->in_use);
+		return -EIO;
 	}
 
-	for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++)
-	{
+	for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
 		memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
 		memset(t->vdau[pgbuf].sregs, 0, sizeof(t->vdau[0].sregs));
 		memset(t->vdau[pgbuf].laststat, 0, sizeof(t->vdau[0].laststat));
@@ -668,13 +662,7 @@
 		t->is_searching[pgbuf] = false;
 	}
 	t->virtual_mode = false;
-	unlock_kernel();
 	return 0;
-
- fail:
-	video_exclusive_release(inode,file);
-	unlock_kernel();
-	return err;
 }
 
 
@@ -682,10 +670,11 @@
 static int saa5249_release(struct inode *inode, struct file *file)
 {
 	struct video_device *vd = video_devdata(file);
-	struct saa5249_device *t=vd->priv;
+	struct saa5249_device *t = vd->priv;
+
 	i2c_senddata(t, 1, 0x20, -1);		/* Turn off CCT */
 	i2c_senddata(t, 5, 3, 3, -1);		/* Turn off TV-display */
-	video_exclusive_release(inode,file);
+	clear_bit(0, &t->in_use);
 	return 0;
 }
 
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 2ff00bc..c635cff 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -113,6 +113,7 @@
 	signed char contrast;
 	signed char color;
 	signed char hue;
+	unsigned long in_use;
 };
 
 /*
@@ -184,10 +185,27 @@
 static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
 			      size_t count, loff_t *ppos);
 
+static int w9966_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct w9966_dev *cam = vdev->priv;
+
+	return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0;
+}
+
+static int w9966_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct w9966_dev *cam = vdev->priv;
+
+	clear_bit(0, &cam->in_use);
+	return 0;
+}
+
 static const struct file_operations w9966_fops = {
 	.owner		= THIS_MODULE,
-	.open           = video_exclusive_open,
-	.release        = video_exclusive_release,
+	.open           = w9966_exclusive_open,
+	.release        = w9966_exclusive_release,
 	.ioctl          = w9966_v4l_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= v4l_compat_ioctl32,