diff options
author | Robby Cai <r63905@freescale.com> | 2014-12-24 20:44:31 +0800 |
---|---|---|
committer | Robby Cai <r63905@freescale.com> | 2014-12-24 21:50:09 +0800 |
commit | 6cb794b964ea4a8f00116c800a7075c3b67fff6b (patch) | |
tree | c346c2584b99c4303ea1e965d20be5c6fba7e7e2 | |
parent | f1ae217b23ac348190dd41bbd488184d2ff8012b (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.c | 11 | ||||
-rw-r--r-- | 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 */ |