Skip to content

Commit

Permalink
[media] s5p-fimc: Add missing FIMC-LITE file operations locking
Browse files Browse the repository at this point in the history
commit 5126f25
"v4l2-dev: add flag to have the core lock all file operations"
introduced an additional bit flag (V4L2_FL_LOCK_ALL_FOPS) that
should be set by drivers that use the v4l2 core lock for all file
operations. Since this driver has been merged at the same time as
the core changes it doesn't set this flags and thus its all file
operations except IOCTL are not properly serialized. Fix this by
adding file ops locking in the driver.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed Jul 7, 2012
1 parent 5aedc10 commit 4e39da0
Showing 1 changed file with 44 additions and 17 deletions.
61 changes: 44 additions & 17 deletions drivers/media/video/s5p-fimc/fimc-lite.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,34 +453,42 @@ static int fimc_lite_open(struct file *file)
struct fimc_lite *fimc = video_drvdata(file);
int ret;

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

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

if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA)
return 0;
goto done;

ret = v4l2_fh_open(file);
if (ret < 0)
return ret;
goto done;

ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity,
true);
if (ret < 0) {
pm_runtime_put_sync(&fimc->pdev->dev);
fimc->ref_count--;
v4l2_fh_release(file);
clear_bit(ST_FLITE_IN_USE, &fimc->state);
}
if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
ret = fimc_pipeline_initialize(&fimc->pipeline,
&fimc->vfd->entity, true);
if (ret < 0) {
pm_runtime_put_sync(&fimc->pdev->dev);
fimc->ref_count--;
v4l2_fh_release(file);
clear_bit(ST_FLITE_IN_USE, &fimc->state);
}

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

static int fimc_lite_close(struct file *file)
{
struct fimc_lite *fimc = video_drvdata(file);
int ret;

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

if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
clear_bit(ST_FLITE_IN_USE, &fimc->state);
Expand All @@ -494,20 +502,39 @@ static int fimc_lite_close(struct file *file)
if (fimc->ref_count == 0)
vb2_queue_release(&fimc->vb_queue);

return v4l2_fh_release(file);
ret = v4l2_fh_release(file);

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

static unsigned int fimc_lite_poll(struct file *file,
struct poll_table_struct *wait)
{
struct fimc_lite *fimc = video_drvdata(file);
return vb2_poll(&fimc->vb_queue, file, wait);
int ret;

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

ret = vb2_poll(&fimc->vb_queue, file, wait);
mutex_unlock(&fimc->lock);

return ret;
}

static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
{
struct fimc_lite *fimc = video_drvdata(file);
return vb2_mmap(&fimc->vb_queue, vma);
int ret;

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

ret = vb2_mmap(&fimc->vb_queue, vma);
mutex_unlock(&fimc->lock);

return ret;
}

static const struct v4l2_file_operations fimc_lite_fops = {
Expand Down

0 comments on commit 4e39da0

Please sign in to comment.