Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2d430af authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-fimc: Remove V4L2_FL_LOCK_ALL_FOPS flag



This patch adds locking for open(), close(), poll() and mmap()
file operations in the driver as a follow up to the changes
done in commit 5126f259
"v4l2-dev: add flag to have the core lock all file operations".

Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 837c7e42
Loading
Loading
Loading
Loading
+52 −26
Original line number Diff line number Diff line
@@ -480,48 +480,59 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc);
static int fimc_capture_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret;
	int ret = -EBUSY;

	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	if (fimc_m2m_active(fimc))
		return -EBUSY;
		goto unlock;

	set_bit(ST_CAPT_BUSY, &fimc->state);
	ret = pm_runtime_get_sync(&fimc->pdev->dev);
	if (ret < 0)
		return ret;
		goto unlock;

	ret = v4l2_fh_open(file);
	if (ret)
		return ret;

	if (++fimc->vid_cap.refcnt != 1)
		return 0;
	if (ret) {
		pm_runtime_put(&fimc->pdev->dev);
		goto unlock;
	}

	if (++fimc->vid_cap.refcnt == 1) {
		ret = fimc_pipeline_initialize(&fimc->pipeline,
				       &fimc->vid_cap.vfd->entity, true);

		if (!ret && !fimc->vid_cap.user_subdev_api)
			ret = fimc_capture_set_default_format(fimc);

		if (!ret)
			ret = fimc_capture_ctrls_create(fimc);

		if (ret < 0) {
			clear_bit(ST_CAPT_BUSY, &fimc->state);
			pm_runtime_put_sync(&fimc->pdev->dev);
			fimc->vid_cap.refcnt--;
			v4l2_fh_release(file);
		return ret;
		}
	ret = fimc_capture_ctrls_create(fimc);

	if (!ret && !fimc->vid_cap.user_subdev_api)
		ret = fimc_capture_set_default_format(fimc);

	}
unlock:
	mutex_unlock(&fimc->lock);
	return ret;
}

static int fimc_capture_close(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret;

	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	if (--fimc->vid_cap.refcnt == 0) {
		clear_bit(ST_CAPT_BUSY, &fimc->state);
		fimc_stop_capture(fimc, false);
@@ -535,22 +546,40 @@ static int fimc_capture_close(struct file *file)
		vb2_queue_release(&fimc->vid_cap.vbq);
		fimc_ctrls_delete(fimc->vid_cap.ctx);
	}
	return v4l2_fh_release(file);

	ret = v4l2_fh_release(file);

	mutex_unlock(&fimc->lock);
	return ret;
}

static unsigned int fimc_capture_poll(struct file *file,
				      struct poll_table_struct *wait)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret;

	return vb2_poll(&fimc->vid_cap.vbq, file, wait);
	if (mutex_lock_interruptible(&fimc->lock))
		return POLL_ERR;

	ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
	mutex_unlock(&fimc->lock);

	return ret;
}

static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct fimc_dev *fimc = video_drvdata(file);
	int ret;

	return vb2_mmap(&fimc->vid_cap.vbq, vma);
	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	ret = vb2_mmap(&fimc->vid_cap.vbq, vma);
	mutex_unlock(&fimc->lock);

	return ret;
}

static const struct v4l2_file_operations fimc_capture_fops = {
@@ -1589,10 +1618,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
	vfd->minor	= -1;
	vfd->release	= video_device_release;
	vfd->lock	= &fimc->lock;
	/* 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);

	video_set_drvdata(vfd, fimc);

	vid_cap = &fimc->vid_cap;
+35 −10
Original line number Diff line number Diff line
@@ -642,21 +642,25 @@ static int fimc_m2m_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
	struct fimc_ctx *ctx;
	int ret;
	int ret = -EBUSY;

	dbg("pid: %d, state: 0x%lx, refcnt: %d",
	    task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;
	/*
	 * Return if the corresponding video capture node
	 * is already opened.
	 */
	if (fimc->vid_cap.refcnt > 0)
		return -EBUSY;
		goto unlock;

	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;
	if (!ctx) {
		ret = -ENOMEM;
		goto unlock;
	}
	v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
	ctx->fimc_dev = fimc;

@@ -687,6 +691,8 @@ static int fimc_m2m_open(struct file *file)

	if (fimc->m2m.refcnt++ == 0)
		set_bit(ST_M2M_RUN, &fimc->state);

	mutex_unlock(&fimc->lock);
	return 0;

error_c:
@@ -695,6 +701,8 @@ static int fimc_m2m_open(struct file *file)
	v4l2_fh_del(&ctx->fh);
	v4l2_fh_exit(&ctx->fh);
	kfree(ctx);
unlock:
	mutex_unlock(&fimc->lock);
	return ret;
}

@@ -706,6 +714,9 @@ static int fimc_m2m_release(struct file *file)
	dbg("pid: %d, state: 0x%lx, refcnt= %d",
		task_pid_nr(current), fimc->state, fimc->m2m.refcnt);

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	v4l2_m2m_ctx_release(ctx->m2m_ctx);
	fimc_ctrls_delete(ctx);
	v4l2_fh_del(&ctx->fh);
@@ -714,6 +725,8 @@ static int fimc_m2m_release(struct file *file)
	if (--fimc->m2m.refcnt <= 0)
		clear_bit(ST_M2M_RUN, &fimc->state);
	kfree(ctx);

	mutex_unlock(&fimc->lock);
	return 0;
}

@@ -721,16 +734,32 @@ static unsigned int fimc_m2m_poll(struct file *file,
				  struct poll_table_struct *wait)
{
	struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
	struct fimc_dev *fimc = ctx->fimc_dev;
	int ret;

	return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
	mutex_unlock(&fimc->lock);

	return ret;
}


static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
	struct fimc_dev *fimc = ctx->fimc_dev;
	int ret;

	if (mutex_lock_interruptible(&fimc->lock))
		return -ERESTARTSYS;

	return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
	ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
	mutex_unlock(&fimc->lock);

	return ret;
}

static const struct v4l2_file_operations fimc_m2m_fops = {
@@ -772,10 +801,6 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
	vfd->minor = -1;
	vfd->release = video_device_release;
	vfd->lock = &fimc->lock;
	/* 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);

	snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
	video_set_drvdata(vfd, fimc);