u32 value = 0;
        u32 tmp = 0;
 
-       mutex_lock(&dev->lock);
-
        for (i = 0; i < MAX_DECODERS; i++) {
                /* set video format NTSC-M */
                value = cx25821_i2c_read(&dev->i2c_bus[0],
        value |= 0x00080200;
        ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
 
-       mutex_unlock(&dev->lock);
-
        return ret_val;
 }
 
        u32 value = 0;
        u32 tmp = 0;
 
-       mutex_lock(&dev->lock);
-
        for (i = 0; i < MAX_DECODERS; i++) {
                /* set video format PAL-BDGHI */
                value = cx25821_i2c_read(&dev->i2c_bus[0],
        value &= 0xFFF7FDFF;
        ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
 
-       mutex_unlock(&dev->lock);
-
        return ret_val;
 }
 
        u32 vscale = 0x0;
        const int MAX_WIDTH = 720;
 
-       mutex_lock(&dev->lock);
-
        /* validate the width */
        if (width > MAX_WIDTH) {
                pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
                cx25821_i2c_write(&dev->i2c_bus[0],
                                VSCALE_CTRL + (0x200 * decoder), vscale);
        }
-
-       mutex_unlock(&dev->lock);
 }
 
 static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
        u32 tmp = 0;
        u32 disp_cnt_reg = DISP_AB_CNT;
 
-       mutex_lock(&dev->lock);
-
        /* no support */
        if (decoder < VDEC_A || decoder > VDEC_H) {
-               mutex_unlock(&dev->lock);
                return;
        }
 
        }
 
        cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
-
-       mutex_unlock(&dev->lock);
 }
 
 /* Map to Medusa register setting */
        int value = 0;
        u32 val = 0, tmp = 0;
 
-       mutex_lock(&dev->lock);
        if ((brightness > VIDEO_PROCAMP_MAX) ||
            (brightness < VIDEO_PROCAMP_MIN)) {
-               mutex_unlock(&dev->lock);
                return -1;
        }
        ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
        val &= 0xFFFFFF00;
        ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
                        VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
-       mutex_unlock(&dev->lock);
        return ret_val;
 }
 
        int value = 0;
        u32 val = 0, tmp = 0;
 
-       mutex_lock(&dev->lock);
-
        if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
-               mutex_unlock(&dev->lock);
                return -1;
        }
 
        ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
                        VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
 
-       mutex_unlock(&dev->lock);
        return ret_val;
 }
 
        int value = 0;
        u32 val = 0, tmp = 0;
 
-       mutex_lock(&dev->lock);
-
        if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
-               mutex_unlock(&dev->lock);
                return -1;
        }
 
        ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
                        VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
 
-       mutex_unlock(&dev->lock);
        return ret_val;
 }
 
        int value = 0;
        u32 val = 0, tmp = 0;
 
-       mutex_lock(&dev->lock);
-
        if ((saturation > VIDEO_PROCAMP_MAX) ||
            (saturation < VIDEO_PROCAMP_MIN)) {
-               mutex_unlock(&dev->lock);
                return -1;
        }
 
        ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
                        VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
 
-       mutex_unlock(&dev->lock);
        return ret_val;
 }
 
        int ret_val = 0;
        int i = 0;
 
-       mutex_lock(&dev->lock);
-
        _num_decoders = dev->_max_num_decoders;
 
        /* disable Auto source selection on all video decoders */
        if (ret_val < 0)
                goto error;
 
-       mutex_unlock(&dev->lock);
-
        for (i = 0; i < _num_decoders; i++)
                medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
 
-       mutex_lock(&dev->lock);
-
        /* Select monitor as DENC A input, power up the DAC */
        value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
        value &= 0xFF70FF70;
        if (ret_val < 0)
                goto error;
 
-
-       mutex_unlock(&dev->lock);
-
        ret_val = medusa_set_videostandard(dev);
 
-       return ret_val;
-
 error:
-       mutex_unlock(&dev->lock);
        return ret_val;
 }
 
        return 0;
 }
 
-/*
-static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
-       int i;
-
-       if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
-               return -EINVAL;
-       for (i = 0; i < CX25821_CTLS; i++)
-               if (cx25821_ctls[i].v.id == qctrl->id)
-                       break;
-       if (i == CX25821_CTLS) {
-               *qctrl = no_ctl;
-               return 0;
-       }
-       *qctrl = cx25821_ctls[i].v;
-       return 0;
-}
-*/
-
 /* resource management */
-int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
+static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
                    unsigned int bit)
 {
        dprintk(1, "%s()\n", __func__);
                return 1;
 
        /* is it free? */
-       mutex_lock(&dev->lock);
        if (dev->channels[fh->channel_id].resources & bit) {
                /* no, someone else uses it */
-               mutex_unlock(&dev->lock);
                return 0;
        }
        /* it's free, grab it */
        fh->resources |= bit;
        dev->channels[fh->channel_id].resources |= bit;
        dprintk(1, "res: get %d\n", bit);
-       mutex_unlock(&dev->lock);
        return 1;
 }
 
-int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
+static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
 {
        return fh->resources & bit;
 }
 
-int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
+static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
 {
        return fh->dev->channels[fh->channel_id].resources & bit;
 }
 
-void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
+static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
                      unsigned int bits)
 {
        BUG_ON((fh->resources & bits) != bits);
        dprintk(1, "%s()\n", __func__);
 
-       mutex_lock(&dev->lock);
        fh->resources &= ~bits;
        dev->channels[fh->channel_id].resources &= ~bits;
        dprintk(1, "res: put %d\n", bits);
-       mutex_unlock(&dev->lock);
 }
 
 static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
        videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev,
                        &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
                        V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
-                       fh, NULL);
+                       fh, &dev->lock);
 
        dprintk(1, "post videobuf_queue_init()\n");
 
                         loff_t *ppos)
 {
        struct cx25821_fh *fh = file->private_data;
+       struct cx25821_dev *dev = fh->dev;
+       int err;
 
        switch (fh->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+               if (mutex_lock_interruptible(&dev->lock))
+                       return -ERESTARTSYS;
                if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
-                       return -EBUSY;
-
-               return videobuf_read_one(&fh->vidq, data, count, ppos,
+                       err = -EBUSY;
+               else
+                       err = videobuf_read_one(&fh->vidq, data, count, ppos,
                                        file->f_flags & O_NONBLOCK);
+               mutex_unlock(&dev->lock);
+               return err;
 
        default:
-               BUG();
-               return 0;
+               return -ENODEV;
        }
+
 }
 
 static unsigned int video_poll(struct file *file,
        const struct sram_channel *sram_ch =
                dev->channels[0].sram_channels;
 
+       mutex_lock(&dev->lock);
        /* stop the risc engine and fifo */
        cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */
 
                videobuf_queue_cancel(&fh->vidq);
                cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
        }
+       mutex_unlock(&dev->lock);
 
        if (fh->vidq.read_buf) {
                cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
        if (dev->tvnorm == tvnorms)
                return 0;
 
-       mutex_lock(&dev->lock);
        cx25821_set_tvnorm(dev, tvnorms);
-       mutex_unlock(&dev->lock);
 
        medusa_set_videostandard(dev);
 
        if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0)
                return -EINVAL;
 
-       mutex_lock(&dev->lock);
        cx25821_video_mux(dev, i);
-       mutex_unlock(&dev->lock);
        return 0;
 }
 
        .read = video_read,
        .poll = video_poll,
        .mmap = cx25821_video_mmap,
-       .ioctl = cx25821_video_ioctl,
+       .unlocked_ioctl = cx25821_video_ioctl,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
        int err;
        int i;
 
+       /* initial device configuration */
+       dev->tvnorm = V4L2_STD_NTSC_M,
+       cx25821_set_tvnorm(dev, dev->tvnorm);
+
        spin_lock_init(&dev->slock);
 
        for (i = 0; i < VID_CHANNEL_NUM; ++i) {
                        err = hdl->error;
                        goto fail_unreg;
                }
+               err = v4l2_ctrl_handler_setup(hdl);
+               if (err)
+                       goto fail_unreg;
 
                cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper,
                        dev->channels[i].sram_channels->dma_ctl, 0x11, 0);
                *vdev = cx25821_video_device;
                vdev->v4l2_dev = &dev->v4l2_dev;
                vdev->ctrl_handler = hdl;
+               vdev->lock = &dev->lock;
                snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
                video_set_drvdata(vdev, dev);
 
        /* set PCI interrupt */
        cx_set(PCI_INT_MSK, 0xff);
 
-       /* initial device configuration */
-       mutex_lock(&dev->lock);
-       dev->tvnorm = V4L2_STD_NTSC_M,
-       cx25821_set_tvnorm(dev, dev->tvnorm);
-       mutex_unlock(&dev->lock);
-
        return 0;
 
 fail_unreg: