summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Cai <r63905@freescale.com>2014-12-24 20:44:31 +0800
committerRobby Cai <r63905@freescale.com>2014-12-24 21:50:09 +0800
commit6cb794b964ea4a8f00116c800a7075c3b67fff6b (patch)
treec346c2584b99c4303ea1e965d20be5c6fba7e7e2
parentf1ae217b23ac348190dd41bbd488184d2ff8012b (diff)
MLK-10057 PxP V4L2 output: force to call pxp_streamoff when device closes
By previous implementation, there's the possibility that last picture remains on screen when the program exits. This can be reproduced by not calling STREAMOFF ioctl in v4l2 output application or just trying to kill the v4l2 output program. The driver has faults to handle this case, since it depends on 'pxp->s0_vbq.streaming' variable be true in close() function to call pxp_streamoff() while the variable is set to 0 after the application calls munmap(). The driver should call pxp_streamoff() even if the application does not call STREAMOFF ioctl. This patch uses the local 'streaming' variable to track the streaming status to fix this problem. Signed-off-by: Robby Cai <r63905@freescale.com>
-rw-r--r--drivers/media/platform/mxc/output/mxc_pxp_v4l2.c11
-rw-r--r--drivers/media/platform/mxc/output/mxc_pxp_v4l2.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
index 5d5dfd338e4c..8652be6f4e4d 100644
--- a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
+++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
@@ -690,11 +690,13 @@ static int pxp_streamon(struct file *file, void *priv,
if (t != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
- if (pxp->s0_vbq.streaming) {
+ if (pxp->streaming) {
dev_err(&pxp->pdev->dev, "v4l2 output already run!");
return -EBUSY;
}
+ pxp->streaming = true;
+
_get_cur_fb_blank(pxp);
set_fb_blank(FB_BLANK_UNBLANK);
@@ -715,13 +717,15 @@ static int pxp_streamoff(struct file *file, void *priv,
if ((t != V4L2_BUF_TYPE_VIDEO_OUTPUT))
return -EINVAL;
- if (pxp->s0_vbq.streaming) {
+ if (pxp->streaming) {
ret = videobuf_streamoff(&pxp->s0_vbq);
pxp_show_buf(pxp, (unsigned long)pxp->fb.base);
if (pxp->fb_blank)
set_fb_blank(FB_BLANK_POWERDOWN);
+
+ pxp->streaming = false;
}
return ret;
@@ -1151,8 +1155,9 @@ out:
static int pxp_close(struct file *file)
{
struct pxps *pxp = video_get_drvdata(video_devdata(file));
- if (pxp->s0_vbq.streaming)
+ if (pxp->streaming)
pxp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+
videobuf_stop(&pxp->s0_vbq);
videobuf_mmap_free(&pxp->s0_vbq);
pxp->active = NULL;
diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h
index 8abb4c17f3fd..8f45c54e89d8 100644
--- a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h
+++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.h
@@ -53,6 +53,7 @@ struct pxps {
struct video_device *vdev;
struct videobuf_queue s0_vbq;
+ bool streaming;
struct pxp_buffer *active;
struct list_head outq;
struct pxp_channel *pxp_channel[1]; /* We need 1 channel */