diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-03-25 15:50:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-04-04 19:24:32 -0400 |
commit | 9ea89e2b62c70f3986c89363818a89c8c11c96c4 (patch) | |
tree | 4b59e979af0bac64ff3fe0936fa1ac6efd4b6b9d | |
parent | 439797980af4bddfc2b86a44ddb573c5e48a1fcc (diff) |
[media] exynos4-is: Ensure proper media pipeline state on device close
Make sure media_entity_pipeline_stop() is called on video device
close in cases where there was VIDIOC_STREAMON ioctl and no
VIDIOC_STREAMOFF. This patch fixes media entities stream_count
state which could prevent links from being disconnected, due to
non-zero stream_count.
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>
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-capture.c | 18 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-core.h | 1 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.c | 18 | ||||
-rw-r--r-- | drivers/media/platform/exynos4-is/fimc-lite.h | 1 |
4 files changed, 29 insertions, 9 deletions
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 965b07f36e3c..28c6b26f6ff5 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
@@ -551,6 +551,7 @@ unlock: | |||
551 | static int fimc_capture_release(struct file *file) | 551 | static int fimc_capture_release(struct file *file) |
552 | { | 552 | { |
553 | struct fimc_dev *fimc = video_drvdata(file); | 553 | struct fimc_dev *fimc = video_drvdata(file); |
554 | struct fimc_vid_cap *vc = &fimc->vid_cap; | ||
554 | int ret; | 555 | int ret; |
555 | 556 | ||
556 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); | 557 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); |
@@ -558,6 +559,10 @@ static int fimc_capture_release(struct file *file) | |||
558 | mutex_lock(&fimc->lock); | 559 | mutex_lock(&fimc->lock); |
559 | 560 | ||
560 | if (v4l2_fh_is_singular_file(file)) { | 561 | if (v4l2_fh_is_singular_file(file)) { |
562 | if (vc->streaming) { | ||
563 | media_entity_pipeline_stop(&vc->vfd.entity); | ||
564 | vc->streaming = false; | ||
565 | } | ||
561 | clear_bit(ST_CAPT_BUSY, &fimc->state); | 566 | clear_bit(ST_CAPT_BUSY, &fimc->state); |
562 | fimc_stop_capture(fimc, false); | 567 | fimc_stop_capture(fimc, false); |
563 | fimc_pipeline_call(fimc, close, &fimc->pipeline); | 568 | fimc_pipeline_call(fimc, close, &fimc->pipeline); |
@@ -1243,8 +1248,10 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
1243 | } | 1248 | } |
1244 | 1249 | ||
1245 | ret = vb2_ioctl_streamon(file, priv, type); | 1250 | ret = vb2_ioctl_streamon(file, priv, type); |
1246 | if (!ret) | 1251 | if (!ret) { |
1252 | vc->streaming = true; | ||
1247 | return ret; | 1253 | return ret; |
1254 | } | ||
1248 | 1255 | ||
1249 | err_p_stop: | 1256 | err_p_stop: |
1250 | media_entity_pipeline_stop(entity); | 1257 | media_entity_pipeline_stop(entity); |
@@ -1258,11 +1265,12 @@ static int fimc_cap_streamoff(struct file *file, void *priv, | |||
1258 | int ret; | 1265 | int ret; |
1259 | 1266 | ||
1260 | ret = vb2_ioctl_streamoff(file, priv, type); | 1267 | ret = vb2_ioctl_streamoff(file, priv, type); |
1268 | if (ret < 0) | ||
1269 | return ret; | ||
1261 | 1270 | ||
1262 | if (ret == 0) | 1271 | media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity); |
1263 | media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity); | 1272 | fimc->vid_cap.streaming = false; |
1264 | 1273 | return 0; | |
1265 | return ret; | ||
1266 | } | 1274 | } |
1267 | 1275 | ||
1268 | static int fimc_cap_reqbufs(struct file *file, void *priv, | 1276 | static int fimc_cap_reqbufs(struct file *file, void *priv, |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index 7d361b24dfd7..d2fe162485a3 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h | |||
@@ -319,6 +319,7 @@ struct fimc_vid_cap { | |||
319 | int buf_index; | 319 | int buf_index; |
320 | unsigned int frame_count; | 320 | unsigned int frame_count; |
321 | unsigned int reqbufs_count; | 321 | unsigned int reqbufs_count; |
322 | bool streaming; | ||
322 | int input_index; | 323 | int input_index; |
323 | int refcnt; | 324 | int refcnt; |
324 | u32 input; | 325 | u32 input; |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index b11e3583b9fa..cb196b85a858 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -507,6 +507,10 @@ static int fimc_lite_release(struct file *file) | |||
507 | 507 | ||
508 | if (v4l2_fh_is_singular_file(file) && | 508 | if (v4l2_fh_is_singular_file(file) && |
509 | atomic_read(&fimc->out_path) == FIMC_IO_DMA) { | 509 | atomic_read(&fimc->out_path) == FIMC_IO_DMA) { |
510 | if (fimc->streaming) { | ||
511 | media_entity_pipeline_stop(&fimc->vfd.entity); | ||
512 | fimc->streaming = false; | ||
513 | } | ||
510 | clear_bit(ST_FLITE_IN_USE, &fimc->state); | 514 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
511 | fimc_lite_stop_capture(fimc, false); | 515 | fimc_lite_stop_capture(fimc, false); |
512 | fimc_pipeline_call(fimc, close, &fimc->pipeline); | 516 | fimc_pipeline_call(fimc, close, &fimc->pipeline); |
@@ -798,8 +802,11 @@ static int fimc_lite_streamon(struct file *file, void *priv, | |||
798 | goto err_p_stop; | 802 | goto err_p_stop; |
799 | 803 | ||
800 | ret = vb2_ioctl_streamon(file, priv, type); | 804 | ret = vb2_ioctl_streamon(file, priv, type); |
801 | if (!ret) | 805 | if (!ret) { |
806 | fimc->streaming = true; | ||
802 | return ret; | 807 | return ret; |
808 | } | ||
809 | |||
803 | err_p_stop: | 810 | err_p_stop: |
804 | media_entity_pipeline_stop(entity); | 811 | media_entity_pipeline_stop(entity); |
805 | return 0; | 812 | return 0; |
@@ -812,9 +819,12 @@ static int fimc_lite_streamoff(struct file *file, void *priv, | |||
812 | int ret; | 819 | int ret; |
813 | 820 | ||
814 | ret = vb2_ioctl_streamoff(file, priv, type); | 821 | ret = vb2_ioctl_streamoff(file, priv, type); |
815 | if (ret == 0) | 822 | if (ret < 0) |
816 | media_entity_pipeline_stop(&fimc->vfd.entity); | 823 | return ret; |
817 | return ret; | 824 | |
825 | media_entity_pipeline_stop(&fimc->vfd.entity); | ||
826 | fimc->streaming = false; | ||
827 | return 0; | ||
818 | } | 828 | } |
819 | 829 | ||
820 | static int fimc_lite_reqbufs(struct file *file, void *priv, | 830 | static int fimc_lite_reqbufs(struct file *file, void *priv, |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h index 8a8d26f58344..71fed5129e30 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.h +++ b/drivers/media/platform/exynos4-is/fimc-lite.h | |||
@@ -166,6 +166,7 @@ struct fimc_lite { | |||
166 | int ref_count; | 166 | int ref_count; |
167 | 167 | ||
168 | struct fimc_lite_events events; | 168 | struct fimc_lite_events events; |
169 | bool streaming; | ||
169 | }; | 170 | }; |
170 | 171 | ||
171 | static inline bool fimc_lite_active(struct fimc_lite *fimc) | 172 | static inline bool fimc_lite_active(struct fimc_lite *fimc) |