config VIDEO_DEV
        tristate "Video For Linux"
-       depends on BKL # used in many drivers for ioctl handling, need to kill
        ---help---
          V4L core support for video capture and overlay devices, webcams and
          AM/FM radio cards.
 
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
                        dev = h;
        }
 
-       if (dev == NULL) {
-               unlock_kernel();
+       if (dev == NULL)
                return -ENODEV;
-       }
+
        mutex_lock(&dev->lock);
 
        /* allocate + initialize per filehandle data */
 
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
        /* allocate + initialize per filehandle data */
        fh = kzalloc(sizeof(*fh), GFP_KERNEL);
-       if (NULL == fh) {
-               unlock_kernel();
+       if (!fh)
                return -ENOMEM;
-       }
-
-       lock_kernel();
 
        file->private_data = fh;
        fh->dev      = dev;
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct cx23885_buffer),
                            fh, NULL);
-       unlock_kernel();
-
        return 0;
 }
 
 
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
        if (NULL == fh)
                return -ENOMEM;
 
-       lock_kernel();
-
        file->private_data = fh;
        fh->dev      = dev;
        fh->radio    = radio;
 
        dprintk(1, "post videobuf_queue_init()\n");
 
-       unlock_kernel();
-
        return 0;
 }
 
 
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/usb.h>
 #include "se401.h"
        struct usb_se401 *se401 = (struct usb_se401 *)dev;
        int err = 0;
 
-       lock_kernel();
+       mutex_lock(&se401->lock);
        if (se401->user) {
-               unlock_kernel();
+               mutex_unlock(&se401->lock);
                return -EBUSY;
        }
        se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
        else
                err = -ENOMEM;
        se401->user = !err;
-       unlock_kernel();
+       mutex_unlock(&se401->lock);
 
        return err;
 }
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include <linux/usb.h>
 #include <linux/mm.h>
        vdev = video_devdata(fp);
        dev = vdev_to_camera(vdev);
 
-       lock_kernel();
        if (dev == NULL || !is_present(dev)) {
-               unlock_kernel();
                return -ENXIO;
        }
        fp->private_data = dev;
        usb_autopm_get_interface(dev->interface);
-       unlock_kernel();
 
        return 0;
 }
 
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/firmware.h>
-#include <linux/smp_lock.h>
 
 #include "vendorcmds.h"
 #include "pd-common.h"
        /*unregister v4l2 device */
        v4l2_device_unregister(&pd->v4l2_dev);
 
-       lock_kernel();
-       {
-               pd_dvb_usb_device_exit(pd);
-               poseidon_fm_exit(pd);
+       pd_dvb_usb_device_exit(pd);
+       poseidon_fm_exit(pd);
 
-               poseidon_audio_free(pd);
-               pd_video_exit(pd);
-       }
-       unlock_kernel();
+       poseidon_audio_free(pd);
+       pd_video_exit(pd);
 
        usb_set_intfdata(interface, NULL);
        kref_put(&pd->kref, poseidon_delete);
 
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
                return -EINVAL;
        }
 
-       /* the videodev_lock held above us protects us from
-        * simultaneous opens...for now. we probably shouldn't
-        * rely on this fact forever.
+       /* cam_lock/open_count protects us from simultaneous opens
+        * ... for now. we probably shouldn't rely on this fact forever.
         */
 
-       lock_kernel();
+       mutex_lock(&cam->cam_lock);
        if (cam->open_count > 0) {
                printk(KERN_INFO
                       "vicam_open called on already opened camera");
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -EBUSY;
        }
 
        cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
        if (!cam->raw_image) {
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
        cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
        if (!cam->framebuf) {
                kfree(cam->raw_image);
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
        if (!cam->cntrlbuf) {
                kfree(cam->raw_image);
                rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
-               unlock_kernel();
+               mutex_unlock(&cam->cam_lock);
                return -ENOMEM;
        }
 
+       cam->needsDummyRead = 1;
+       cam->open_count++;
+
+       file->private_data = cam;
+       mutex_unlock(&cam->cam_lock);
+
+
        // First upload firmware, then turn the camera on
 
        if (!cam->is_initialized) {
 
        set_camera_power(cam, 1);
 
-       cam->needsDummyRead = 1;
-       cam->open_count++;
-
-       file->private_data = cam;
-       unlock_kernel();
-
        return 0;
 }
 
 
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
                        mutex_unlock(vdev->lock);
        } else if (vdev->fops->ioctl) {
                /* TODO: convert all drivers to unlocked_ioctl */
-               lock_kernel();
+               static DEFINE_MUTEX(v4l2_ioctl_mutex);
+
+               mutex_lock(&v4l2_ioctl_mutex);
                if (video_is_registered(vdev))
                        ret = vdev->fops->ioctl(filp, cmd, arg);
-               unlock_kernel();
+               mutex_unlock(&v4l2_ioctl_mutex);
        } else
                ret = -ENOTTY;
 
 
        struct videocodec *vfe; /* video front end */
 
        struct mutex resource_lock;     /* prevent evil stuff */
+       struct mutex other_lock;        /* please merge with above */
 
        u8 initialized;         /* flag if zoran has been correctly initialized */
        int user;               /* number of current users */
 
        snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
        spin_lock_init(&zr->spinlock);
        mutex_init(&zr->resource_lock);
+       mutex_init(&zr->other_lock);
        if (pci_enable_device(pdev))
                goto zr_unreg;
        pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
 
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
        dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
                ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
 
-       lock_kernel();
+       mutex_lock(&zr->other_lock);
 
        if (zr->user >= 2048) {
                dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
        file->private_data = fh;
        fh->zr = zr;
        zoran_open_init_session(fh);
-       unlock_kernel();
+       mutex_unlock(&zr->other_lock);
 
        return 0;
 
 fail_fh:
        kfree(fh);
 fail_unlock:
-       unlock_kernel();
+       mutex_unlock(&zr->other_lock);
 
        dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n",
                ZR_DEVNAME(zr), res, zr->user);
 
        /* kernel locks (fs/device.c), so don't do that ourselves
         * (prevents deadlocks) */
-       /*mutex_lock(&zr->resource_lock);*/
+       mutex_lock(&zr->other_lock);
 
        zoran_close_end_session(fh);
 
                        encoder_call(zr, video, s_routing, 2, 0, 0);
                }
        }
+       mutex_unlock(&zr->other_lock);
 
        file->private_data = NULL;
        kfree(fh->overlay_mask);
 #endif
 };
 
+/* please use zr->resource_lock consistently and kill this wrapper */
+static long zoran_ioctl(struct file *file, unsigned int cmd,
+                       unsigned long arg)
+{
+       struct zoran_fh *fh = file->private_data;
+       struct zoran *zr = fh->zr;
+       int ret;
+
+       mutex_lock(&zr->other_lock);
+       ret = video_ioctl2(file, cmd, arg);
+       mutex_unlock(&zr->other_lock);
+
+       return ret;
+}
+
 static const struct v4l2_file_operations zoran_fops = {
        .owner = THIS_MODULE,
        .open = zoran_open,
        .release = zoran_close,
-       .ioctl = video_ioctl2,
+       .unlocked_ioctl = zoran_ioctl,
        .read = zoran_read,
        .write = zoran_write,
        .mmap = zoran_mmap,