From 6cb794b964ea4a8f00116c800a7075c3b67fff6b Mon Sep 17 00:00:00 2001 From: Robby Cai Date: Wed, 24 Dec 2014 20:44:31 +0800 Subject: 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 --- drivers/media/platform/mxc/output/mxc_pxp_v4l2.c | 11 ++++++++--- drivers/media/platform/mxc/output/mxc_pxp_v4l2.h | 1 + 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 */ -- cgit v1.2.3