V4L/DVB (8613): v4l: move BKL down to the driver level.

The BKL is now moved from the video_open function in v4l2-dev.c to the
various drivers. It seems about a third of the drivers already has a
lock of some sort protecting the open(), another third uses
video_exclusive_open (yuck!) and the last third required adding the
BKL in their open function.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 70c65a7..3a4eb44 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -407,15 +407,18 @@
 {
 	struct dsbr100_device *radio=video_get_drvdata(video_devdata(file));
 
+	lock_kernel();
 	radio->users = 1;
 	radio->muted = 1;
 
 	if (dsbr100_start(radio)<0) {
 		warn("Radio did not start up properly");
 		radio->users = 0;
+		unlock_kernel();
 		return -EIO;
 	}
 	dsbr100_setfreq(radio, radio->curfreq);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 16c7ef2..337d557 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -1074,6 +1074,7 @@
 	struct si470x_device *radio = video_get_drvdata(video_devdata(file));
 	int retval;
 
+	lock_kernel();
 	radio->users++;
 
 	retval = usb_autopm_get_interface(radio->intf);
@@ -1090,6 +1091,7 @@
 	}
 
 done:
+	unlock_kernel();
 	return retval;
 }
 
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 933eaef..c3526d0 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3227,6 +3227,7 @@
 
 	dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
 
+	lock_kernel();
 	for (i = 0; i < bttv_num; i++) {
 		if (bttvs[i].video_dev &&
 		    bttvs[i].video_dev->minor == minor) {
@@ -3241,16 +3242,20 @@
 			break;
 		}
 	}
-	if (NULL == btv)
+	if (NULL == btv) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
 		btv->c.nr,v4l2_type_names[type]);
 
 	/* allocate per filehandle data */
 	fh = kmalloc(sizeof(*fh),GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 	file->private_data = fh;
 	*fh = btv->init;
 	fh->type = type;
@@ -3290,6 +3295,7 @@
 	bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
 
 	bttv_field_count(btv);
+	unlock_kernel();
 	return 0;
 }
 
@@ -3430,21 +3436,26 @@
 
 	dprintk("bttv: open minor=%d\n",minor);
 
+	lock_kernel();
 	for (i = 0; i < bttv_num; i++) {
 		if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
 			btv = &bttvs[i];
 			break;
 		}
 	}
-	if (NULL == btv)
+	if (NULL == btv) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	dprintk("bttv%d: open called (radio)\n",btv->c.nr);
 
 	/* allocate per filehandle data */
 	fh = kmalloc(sizeof(*fh), GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 	file->private_data = fh;
 	*fh = btv->init;
 	v4l2_prio_open(&btv->prio, &fh->prio);
@@ -3457,6 +3468,7 @@
 	audio_input(btv,TVAUDIO_INPUT_RADIO);
 
 	mutex_unlock(&btv->lock);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 5405c30..e9994c8 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1476,9 +1476,12 @@
 {
 	struct cafe_camera *cam;
 
+	lock_kernel();
 	cam = cafe_find_dev(iminor(inode));
-	if (cam == NULL)
+	if (cam == NULL) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 	filp->private_data = cam;
 
 	mutex_lock(&cam->s_mutex);
@@ -1490,6 +1493,7 @@
 	}
 	(cam->users)++;
 	mutex_unlock(&cam->s_mutex);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 7b0e8c0..93777d0 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1583,6 +1583,7 @@
 
 	dprintk(2, "%s()\n", __func__);
 
+	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
 		if (h->v4l_device->minor == minor) {
@@ -1591,13 +1592,17 @@
 		}
 	}
 
-	if (dev == NULL)
+	if (dev == NULL) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 
 	file->private_data = fh;
 	fh->dev      = dev;
@@ -1608,6 +1613,7 @@
 			    V4L2_FIELD_INTERLACED,
 			    sizeof(struct cx23885_buffer),
 			    fh);
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 6047c78..d9bef1a 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -731,6 +731,7 @@
 	enum v4l2_buf_type type = 0;
 	int radio = 0;
 
+	lock_kernel();
 	list_for_each(list, &cx23885_devlist) {
 		h = list_entry(list, struct cx23885_dev, devlist);
 		if (h->video_dev->minor == minor) {
@@ -748,16 +749,20 @@
 			dev   = h;
 		}
 	}
-	if (NULL == dev)
+	if (NULL == dev) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	dprintk(1, "open minor=%d radio=%d type=%s\n",
 		minor, radio, v4l2_type_names[type]);
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
@@ -775,6 +780,7 @@
 
 	dprintk(1, "post videobuf_queue_init()\n");
 
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 9a1374a..1b7e2e4 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1057,12 +1057,15 @@
 	struct cx8802_driver *drv = NULL;
 	int err;
 
+	lock_kernel();
 	dev = cx8802_get_device(inode);
 
 	dprintk( 1, "%s\n", __func__);
 
-	if (dev == NULL)
+	if (dev == NULL) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	/* Make sure we can acquire the hardware */
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
@@ -1077,6 +1080,7 @@
 	if (blackbird_initialize_codec(dev) < 0) {
 		if (drv)
 			drv->request_release(drv);
+		unlock_kernel();
 		return -EINVAL;
 	}
 	dprintk(1,"open minor=%d\n",minor);
@@ -1086,6 +1090,7 @@
 	if (NULL == fh) {
 		if (drv)
 			drv->request_release(drv);
+		unlock_kernel();
 		return -ENOMEM;
 	}
 	file->private_data = fh;
@@ -1101,6 +1106,7 @@
 	/* FIXME: locking against other video device */
 	cx88_set_scale(dev->core, dev->width, dev->height,
 			fh->mpegq.field);
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index ef4d56e..61e03d4 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -773,6 +773,7 @@
 	enum v4l2_buf_type type = 0;
 	int radio = 0;
 
+	lock_kernel();
 	list_for_each_entry(h, &cx8800_devlist, devlist) {
 		if (h->video_dev->minor == minor) {
 			dev  = h;
@@ -788,8 +789,10 @@
 			dev   = h;
 		}
 	}
-	if (NULL == dev)
+	if (NULL == dev) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	core = dev->core;
 
@@ -798,8 +801,10 @@
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
@@ -832,6 +837,7 @@
 		cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
 		cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
 	}
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 49ab062..600b340 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1512,6 +1512,7 @@
 	struct em28xx_fh *fh;
 	enum v4l2_buf_type fh_type = 0;
 
+	lock_kernel();
 	list_for_each_entry(h, &em28xx_devlist, devlist) {
 		if (h->vdev->minor == minor) {
 			dev  = h;
@@ -1527,8 +1528,10 @@
 			dev   = h;
 		}
 	}
-	if (NULL == dev)
+	if (NULL == dev) {
+		unlock_kernel();
 		return -ENODEV;
+	}
 
 	em28xx_videodbg("open minor=%d type=%s users=%d\n",
 				minor, v4l2_type_names[fh_type], dev->users);
@@ -1537,6 +1540,7 @@
 	fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
 	if (!fh) {
 		em28xx_errdev("em28xx-video.c: Out of memory?!\n");
+		unlock_kernel();
 		return -ENOMEM;
 	}
 	mutex_lock(&dev->lock);
@@ -1573,6 +1577,7 @@
 			sizeof(struct em28xx_buffer), fh);
 
 	mutex_unlock(&dev->lock);
+	unlock_kernel();
 
 	return errCode;
 }
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index a9ef780..cdaff2f 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -845,15 +845,19 @@
 {
 	int i, err;
 
+	lock_kernel();
 	err = video_exclusive_open(inode, file);
-	if (err < 0)
+	if (err < 0) {
+		unlock_kernel();
 		return err;
+	}
 
 	mchip_hic_stop();
 
 	if (mchip_dma_alloc()) {
 		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
 		video_exclusive_release(inode, file);
+		unlock_kernel();
 		return -ENOBUFS;
 	}
 
@@ -861,6 +865,7 @@
 		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
 	kfifo_reset(meye.grabq);
 	kfifo_reset(meye.doneq);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 00306fa..26ffaa2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -932,6 +932,7 @@
 	unsigned int input_cnt,idx;
 	int ret = 0;
 
+	lock_kernel();
 	dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
 
 	vp = dip->v4lp;
@@ -942,11 +943,13 @@
 	if (!pvr2_hdw_dev_ok(hdw)) {
 		pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
 			   "pvr2_v4l2_open: hardware not ready");
+		unlock_kernel();
 		return -EIO;
 	}
 
 	fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
 	if (!fhp) {
+		unlock_kernel();
 		return -ENOMEM;
 	}
 
@@ -976,6 +979,7 @@
 			   fhp);
 
 		kfree(fhp);
+		unlock_kernel();
 		return ret;
 	}
 
@@ -992,6 +996,7 @@
 			   "Destroying pvr_v4l2_fh id=%p (input map failure)",
 			   fhp);
 		kfree(fhp);
+		unlock_kernel();
 		return -ENOMEM;
 	}
 	input_cnt = 0;
@@ -1015,6 +1020,7 @@
 	v4l2_prio_open(&vp->prio,&fhp->prio);
 
 	fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 92b83fe..de39cf0 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -1457,6 +1457,7 @@
 	int cur_channel = -1;
 	dprintk(1, "s2255: open called (minor=%d)\n", minor);
 
+	lock_kernel();
 	list_for_each(list, &s2255_devlist) {
 		h = list_entry(list, struct s2255_dev, s2255_devlist);
 		for (i = 0; i < MAX_CHANNELS; i++) {
@@ -1469,6 +1470,7 @@
 	}
 
 	if ((NULL == dev) || (cur_channel == -1)) {
+		unlock_kernel();
 		dprintk(1, "s2255: openv4l no dev\n");
 		return -ENODEV;
 	}
@@ -1490,6 +1492,7 @@
 			printk(KERN_INFO "2255 FW load failed.\n");
 			dev->users[cur_channel]--;
 			mutex_unlock(&dev->open_lock);
+			unlock_kernel();
 			return -EFAULT;
 		}
 	} else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) {
@@ -1506,6 +1509,7 @@
 			       "try again\n");
 			dev->users[cur_channel]--;
 			mutex_unlock(&dev->open_lock);
+			unlock_kernel();
 			return -EBUSY;
 		}
 	}
@@ -1515,6 +1519,7 @@
 	if (NULL == fh) {
 		dev->users[cur_channel]--;
 		mutex_unlock(&dev->open_lock);
+		unlock_kernel();
 		return -ENOMEM;
 	}
 
@@ -1548,6 +1553,7 @@
 
 	kref_get(&dev->kref);
 	mutex_unlock(&dev->open_lock);
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 6ee63e6..e2c538e 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/videotext.h>
+#include <linux/smp_lock.h>
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -737,9 +738,12 @@
 	struct saa5246a_device *t = vd->priv;
 	int err;
 
+	lock_kernel();
 	err = video_exclusive_open(inode,file);
-	if (err < 0)
+	if (err < 0) {
+		unlock_kernel();
 		return err;
+	}
 
 	if (t->client==NULL) {
 		err = -ENODEV;
@@ -776,11 +780,13 @@
 		err = -EIO;
 		goto fail;
 	}
+	unlock_kernel();
 
 	return 0;
 
 fail:
 	video_exclusive_release(inode,file);
+	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 0d63973..96c0fdf 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -52,6 +52,7 @@
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <stdarg.h>
 #include <linux/i2c.h>
 #include <linux/videotext.h>
@@ -633,9 +634,12 @@
 	struct saa5249_device *t=vd->priv;
 	int err,pgbuf;
 
+	lock_kernel();
 	err = video_exclusive_open(inode,file);
-	if (err < 0)
+	if (err < 0) {
+		unlock_kernel();
 		return err;
+	}
 
 	if (t->client==NULL) {
 		err = -ENODEV;
@@ -664,10 +668,12 @@
 		t->is_searching[pgbuf] = false;
 	}
 	t->virtual_mode = false;
+	unlock_kernel();
 	return 0;
 
  fail:
 	video_exclusive_release(inode,file);
+	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c0c5d75..6f423d1 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -79,9 +79,11 @@
 	struct saa7134_dev *dev;
 	int err;
 
+	lock_kernel();
 	list_for_each_entry(dev, &saa7134_devlist, devlist)
 		if (dev->empress_dev && dev->empress_dev->minor == minor)
 			goto found;
+	unlock_kernel();
 	return -ENODEV;
  found:
 
@@ -103,6 +105,7 @@
 done_up:
 	mutex_unlock(&dev->empress_tsq.vb_lock);
 done:
+	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 68c2689..8fd3113 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1330,6 +1330,8 @@
 	struct saa7134_fh *fh;
 	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	int radio = 0;
+
+	lock_kernel();
 	list_for_each_entry(dev, &saa7134_devlist, devlist) {
 		if (dev->video_dev && (dev->video_dev->minor == minor))
 			goto found;
@@ -1342,6 +1344,7 @@
 			goto found;
 		}
 	}
+	unlock_kernel();
 	return -ENODEV;
  found:
 
@@ -1350,8 +1353,10 @@
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
-	if (NULL == fh)
+	if (NULL == fh) {
+		unlock_kernel();
 		return -ENOMEM;
+	}
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->radio    = radio;
@@ -1384,6 +1389,7 @@
 		/* switch to video/vbi mode */
 		video_mux(dev,dev->ctl_input);
 	}
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index acceed5..d16bbf0 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -936,14 +936,18 @@
 	struct usb_se401 *se401 = (struct usb_se401 *)dev;
 	int err = 0;
 
-	if (se401->user)
+	lock_kernel();
+	if (se401->user) {
+		unlock_kernel();
 		return -EBUSY;
+	}
 	se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
 	if (se401->fbuf)
 		file->private_data = dev;
 	else
 		err = -ENOMEM;
 	se401->user = !err;
+	unlock_kernel();
 
 	return err;
 }
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index ad36af3..6b1ef5d 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -689,11 +689,15 @@
 	vdev = video_devdata(fp);
 	dev = vdev_to_camera(vdev);
 
-	if (dev == NULL || !is_present(dev))
+	lock_kernel();
+	if (dev == NULL || !is_present(dev)) {
+		unlock_kernel();
 		return -ENXIO;
+	}
 	fp->private_data = vdev;
 	kref_get(&dev->kref);
 	usb_autopm_get_interface(dev->interface);
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 276bded..a3cbe9b 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1882,12 +1882,16 @@
 	struct video_device *vdev = video_devdata(file);
 	struct saa7146 *saa = container_of(vdev, struct saa7146, video_dev);
 
+	lock_kernel();
 	file->private_data = saa;
 
 	saa->user++;
-	if (saa->user > 1)
+	if (saa->user > 1) {
+		unlock_kernel();
 		return 0;	/* device open already, don't reset */
+	}
 	saa->writemode = VID_WRITE_MPEG_VID;	/* default to video */
+	unlock_kernel();
 	return 0;
 }
 
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index dce9474..b21a8d6 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1086,6 +1086,7 @@
 	int err = 0;
 
 	/* we are called with the BKL held */
+	lock_kernel();
 	stv680->user = 1;
 	err = stv_init (stv680);	/* main initialization routine for camera */
 
@@ -1099,6 +1100,7 @@
 	}
 	if (err)
 		stv680->user = 0;
+	unlock_kernel();
 
 	return err;
 }
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 2eb4582..efb878a 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -488,20 +488,24 @@
 	 * rely on this fact forever.
 	 */
 
+	lock_kernel();
 	if (cam->open_count > 0) {
 		printk(KERN_INFO
 		       "vicam_open called on already opened camera");
+		unlock_kernel();
 		return -EBUSY;
 	}
 
 	cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
 	if (!cam->raw_image) {
+		unlock_kernel();
 		return -ENOMEM;
 	}
 
 	cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
 	if (!cam->framebuf) {
 		kfree(cam->raw_image);
+		unlock_kernel();
 		return -ENOMEM;
 	}
 
@@ -509,6 +513,7 @@
 	if (!cam->cntrlbuf) {
 		kfree(cam->raw_image);
 		rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
+		unlock_kernel();
 		return -ENOMEM;
 	}
 
@@ -526,6 +531,7 @@
 	cam->open_count++;
 
 	file->private_data = cam;
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index b977116..b76295a 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -367,6 +367,7 @@
 
 	PDEBUG(DBG_IO, "open");
 
+	lock_kernel();
 	usbvision_reset_powerOffTimer(usbvision);
 
 	if (usbvision->user)
@@ -424,6 +425,7 @@
 	usbvision_empty_framequeues(usbvision);
 
 	PDEBUG(DBG_IO, "success");
+	unlock_kernel();
 	return errCode;
 }
 
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 155fdec..6b9f3cb 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -116,7 +116,6 @@
 
 	if (minor >= VIDEO_NUM_DEVICES)
 		return -ENODEV;
-	lock_kernel();
 	mutex_lock(&videodev_lock);
 	vfl = video_device[minor];
 	if (vfl == NULL) {
@@ -126,7 +125,6 @@
 		vfl = video_device[minor];
 		if (vfl == NULL) {
 			mutex_unlock(&videodev_lock);
-			unlock_kernel();
 			return -ENODEV;
 		}
 	}
@@ -140,7 +138,6 @@
 	}
 	fops_put(old_fops);
 	mutex_unlock(&videodev_lock);
-	unlock_kernel();
 	return err;
 }
 
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 8ba8daa..65c8af1 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -898,9 +898,11 @@
 
 	printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
 
+	lock_kernel();
 	list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
 		if (dev->vfd->minor == minor)
 			goto found;
+	unlock_kernel();
 	return -ENODEV;
 
 found:
@@ -925,8 +927,10 @@
 	}
 unlock:
 	mutex_unlock(&dev->mutex);
-	if (retval)
+	if (retval) {
+		unlock_kernel();
 		return retval;
+	}
 
 	file->private_data = fh;
 	fh->dev      = dev;
@@ -955,6 +959,7 @@
 			sizeof(struct vivi_buffer), fh);
 
 	vivi_start_thread(fh);
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 2dab9ee..4aa1a76 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -1211,6 +1211,7 @@
 	struct zoran_fh *fh;
 	int i, res, first_open = 0, have_module_locks = 0;
 
+	lock_kernel();
 	/* find the device */
 	for (i = 0; i < zoran_num; i++) {
 		if (zoran[i]->video_dev->minor == minor) {
@@ -1321,6 +1322,7 @@
 	file->private_data = fh;
 	fh->zr = zr;
 	zoran_open_init_session(file);
+	unlock_kernel();
 
 	return 0;
 
@@ -1338,6 +1340,7 @@
 	if (zr) {
 		/*mutex_unlock(&zr->resource_lock);*/
 	}
+	unlock_kernel();
 
 	return res;
 }
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 18d1c4b..4e1ef10 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -643,14 +643,18 @@
 
 	cam->skip = 2;
 
+	lock_kernel();
 	err = video_exclusive_open(inode, file);
-	if (err < 0)
+	if (err < 0) {
+		unlock_kernel();
 		return err;
+	}
 
 	if (!cam->framebuf) {
 		cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
 		if (!cam->framebuf) {
 			info("vmalloc_32 failed!");
+			unlock_kernel();
 			return -ENOMEM;
 		}
 	}
@@ -664,6 +668,7 @@
 		if (err < 0) {
 			info("error during open sequence: %d", i);
 			mutex_unlock(&cam->lock);
+			unlock_kernel();
 			return err;
 		}
 	}
@@ -676,6 +681,7 @@
 	mdelay(100);
 
 	mutex_unlock(&cam->lock);
+	unlock_kernel();
 	return 0;
 }