#include <media/saa7146.h>
 #include <linux/module.h>
 
-LIST_HEAD(saa7146_devices);
-DEFINE_MUTEX(saa7146_devices_lock);
-
 static int saa7146_num;
 
 unsigned int saa7146_debug;
           set it explicitly. */
        pci_set_drvdata(pci, &dev->v4l2_dev);
 
-       INIT_LIST_HEAD(&dev->item);
-       list_add_tail(&dev->item,&saa7146_devices);
        saa7146_num++;
 
        err = 0;
 
        iounmap(dev->mem);
        pci_release_region(pdev, 0);
-       list_del(&dev->item);
        pci_disable_device(pdev);
        kfree(dev);
 
 EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
 
 EXPORT_SYMBOL_GPL(saa7146_debug);
-EXPORT_SYMBOL_GPL(saa7146_devices);
-EXPORT_SYMBOL_GPL(saa7146_devices_lock);
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
 
 
        DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
 
-       if (mutex_lock_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(vdev->lock))
                return -ERESTARTSYS;
 
        DEB_D("using: %p\n", dev);
                kfree(fh);
                file->private_data = NULL;
        }
-       mutex_unlock(&saa7146_devices_lock);
+       mutex_unlock(vdev->lock);
        return result;
 }
 
 
        DEB_EE("file:%p\n", file);
 
-       if (mutex_lock_interruptible(&saa7146_devices_lock))
+       if (mutex_lock_interruptible(vdev->lock))
                return -ERESTARTSYS;
 
        if (vdev->vfl_type == VFL_TYPE_VBI) {
        file->private_data = NULL;
        kfree(fh);
 
-       mutex_unlock(&saa7146_devices_lock);
+       mutex_unlock(vdev->lock);
 
        return 0;
 }
        struct video_device *vdev = video_devdata(file);
        struct saa7146_fh *fh = file->private_data;
        struct videobuf_queue *q;
+       int res;
 
        switch (vdev->vfl_type) {
        case VFL_TYPE_GRABBER: {
                return 0;
        }
 
-       return videobuf_mmap_mapper(q,vma);
+       if (mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
+       res = videobuf_mmap_mapper(q, vma);
+       mutex_unlock(vdev->lock);
+       return res;
 }
 
-static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int __fops_poll(struct file *file, struct poll_table_struct *wait)
 {
        struct video_device *vdev = video_devdata(file);
        struct saa7146_fh *fh = file->private_data;
        return res;
 }
 
+static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
+{
+       struct video_device *vdev = video_devdata(file);
+       unsigned int res;
+
+       mutex_lock(vdev->lock);
+       res = __fops_poll(file, wait);
+       mutex_unlock(vdev->lock);
+       return res;
+}
+
 static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
        struct video_device *vdev = video_devdata(file);
        struct saa7146_fh *fh = file->private_data;
+       int ret;
 
        switch (vdev->vfl_type) {
        case VFL_TYPE_GRABBER:
                DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
                       file, data, (unsigned long)count);
 */
-               if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
-                       return saa7146_vbi_uops.read(file,data,count,ppos);
+               if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) {
+                       if (mutex_lock_interruptible(vdev->lock))
+                               return -ERESTARTSYS;
+                       ret = saa7146_vbi_uops.read(file, data, count, ppos);
+                       mutex_unlock(vdev->lock);
+                       return ret;
+               }
                return -EINVAL;
        default:
                BUG();
 {
        struct video_device *vdev = video_devdata(file);
        struct saa7146_fh *fh = file->private_data;
+       int ret;
 
        switch (vdev->vfl_type) {
        case VFL_TYPE_GRABBER:
                return -EINVAL;
        case VFL_TYPE_VBI:
-               if (fh->dev->ext_vv_data->vbi_fops.write)
-                       return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
-               else
-                       return -EINVAL;
+               if (fh->dev->ext_vv_data->vbi_fops.write) {
+                       if (mutex_lock_interruptible(vdev->lock))
+                               return -ERESTARTSYS;
+                       ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
+                       mutex_unlock(vdev->lock);
+                       return ret;
+               }
+               return -EINVAL;
        default:
                BUG();
                return -EINVAL;
        else
                vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
        vfd->release = video_device_release;
-       /* 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, &vfd->flags);
        vfd->lock = &dev->v4l2_lock;
        vfd->v4l2_dev = &dev->v4l2_dev;
        vfd->tvnorms = 0;