summaryrefslogtreecommitdiff
path: root/drivers/media/platform/exynos4-is/fimc-capture.c
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-05-31 11:37:20 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-12 21:55:56 -0300
commit42625fdfbd608f0bdaffaf25e8eb32ef55cddf96 (patch)
treef511d20365c8d7d7fbb7a94185ca28a57b5079ae /drivers/media/platform/exynos4-is/fimc-capture.c
parent4403106d5cfeb438b19e492e29537a00f9b5495a (diff)
[media] exynos4-is: Media graph/video device locking rework
Remove driver private video node reference counters and use entity->use_count instead. This makes the video pipelines power handling more similar to the method used in omap3isp driver. Now the graph mutex is taken always after the video mutex, as it is not possible to ensure apposite order at the all modules. 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>
Diffstat (limited to 'drivers/media/platform/exynos4-is/fimc-capture.c')
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c59
1 files changed, 26 insertions, 33 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 07089de6c669..b6055d2b09d6 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -484,7 +484,6 @@ static int fimc_capture_open(struct file *file)
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
- fimc_md_graph_lock(ve);
mutex_lock(&fimc->lock);
if (fimc_m2m_active(fimc))
@@ -502,6 +501,8 @@ static int fimc_capture_open(struct file *file)
}
if (v4l2_fh_is_singular_file(file)) {
+ fimc_md_graph_lock(ve);
+
ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
&fimc->vid_cap.ve.vdev.entity, true);
if (ret == 0)
@@ -518,18 +519,19 @@ static int fimc_capture_open(struct file *file)
if (ret == 0)
vc->inh_sensor_ctrls = false;
}
+ if (ret == 0)
+ ve->vdev.entity.use_count++;
+
+ fimc_md_graph_unlock(ve);
if (ret < 0) {
clear_bit(ST_CAPT_BUSY, &fimc->state);
pm_runtime_put_sync(&fimc->pdev->dev);
v4l2_fh_release(file);
- } else {
- fimc->vid_cap.refcnt++;
}
}
unlock:
mutex_unlock(&fimc->lock);
- fimc_md_graph_unlock(ve);
return ret;
}
@@ -537,26 +539,32 @@ static int fimc_capture_release(struct file *file)
{
struct fimc_dev *fimc = video_drvdata(file);
struct fimc_vid_cap *vc = &fimc->vid_cap;
+ bool close = v4l2_fh_is_singular_file(file);
int ret;
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
mutex_lock(&fimc->lock);
- if (v4l2_fh_is_singular_file(file)) {
- if (vc->streaming) {
- media_entity_pipeline_stop(&vc->ve.vdev.entity);
- vc->streaming = false;
- }
+ if (close && vc->streaming) {
+ media_entity_pipeline_stop(&vc->ve.vdev.entity);
+ vc->streaming = false;
+ }
+
+ ret = vb2_fop_release(file);
+
+ if (close) {
clear_bit(ST_CAPT_BUSY, &fimc->state);
fimc_stop_capture(fimc, false);
fimc_pipeline_call(fimc, close, &fimc->pipeline);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
- fimc->vid_cap.refcnt--;
+
+ fimc_md_graph_lock(&vc->ve);
+ vc->ve.vdev.entity.use_count--;
+ fimc_md_graph_unlock(&vc->ve);
}
pm_runtime_put(&fimc->pdev->dev);
- ret = vb2_fop_release(file);
mutex_unlock(&fimc->lock);
return ret;
@@ -921,9 +929,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
struct fimc_fmt *ffmt = NULL;
int ret = 0;
- fimc_md_graph_lock(ve);
- mutex_lock(&fimc->lock);
-
if (fimc_jpeg_fourcc(pix->pixelformat)) {
fimc_capture_try_format(ctx, &pix->width, &pix->height,
NULL, &pix->pixelformat,
@@ -934,16 +939,18 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
NULL, &pix->pixelformat,
FIMC_SD_PAD_SOURCE);
- if (!ffmt) {
- ret = -EINVAL;
- goto unlock;
- }
+ if (!ffmt)
+ return -EINVAL;
if (!fimc->vid_cap.user_subdev_api) {
mf.width = pix->width;
mf.height = pix->height;
mf.code = ffmt->mbus_code;
+
+ fimc_md_graph_lock(ve);
fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
+ fimc_md_graph_unlock(ve);
+
pix->width = mf.width;
pix->height = mf.height;
if (ffmt)
@@ -955,9 +962,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
if (ffmt->flags & FMT_FLAGS_COMPRESSED)
fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
pix->plane_fmt, ffmt->memplanes, true);
-unlock:
- mutex_unlock(&fimc->lock);
- fimc_md_graph_unlock(ve);
return ret;
}
@@ -1059,19 +1063,14 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
int ret;
fimc_md_graph_lock(&fimc->vid_cap.ve);
- mutex_lock(&fimc->lock);
/*
* The graph is walked within __fimc_capture_set_format() to set
* the format at subdevs thus the graph mutex needs to be held at
- * this point and acquired before the video mutex, to avoid AB-BA
- * deadlock when fimc_md_link_notify() is called by other thread.
- * Ideally the graph walking and setting format at the whole pipeline
- * should be removed from this driver and handled in userspace only.
+ * this point.
*/
ret = __fimc_capture_set_format(fimc, f);
fimc_md_graph_unlock(&fimc->vid_cap.ve);
- mutex_unlock(&fimc->lock);
return ret;
}
@@ -1790,12 +1789,6 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
ret = fimc_ctrls_create(ctx);
if (ret)
goto err_me_cleanup;
- /*
- * For proper order of acquiring/releasing the video
- * and the graph mutex.
- */
- v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
- v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret)