summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2014-06-23 17:15:02 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-17 12:44:50 -0300
commit9b3e6e2abd7568f9458e927fc4e5eca1b3cde521 (patch)
tree38b39eb67c4df0e1ae98bd3a6c6ff74ade5b53ad
parent9df04e9d9ac6982d16a8a042c8274410ed29fb0e (diff)
downloadlinux-9b3e6e2abd7568f9458e927fc4e5eca1b3cde521.tar.gz
[media] v4l: vsp1: Fix pipeline stop timeout
If the pipeline was already stopped when stopping the stream, no
frame end interrupt will be generated and the driver will time out
waiting for the pipeline to stop.

Fix this by setting the pipeline state to STOPPED when the pipeline is
idle waiting for frames to process, and to STOPPING at stream stop time
only when the pipeline is currently RUNNING.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 9bb156cd3c9e..a60332e3d87f 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -471,7 +471,8 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
 	int ret;
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
-	pipe->state = VSP1_PIPELINE_STOPPING;
+	if (pipe->state == VSP1_PIPELINE_RUNNING)
+		pipe->state = VSP1_PIPELINE_STOPPING;
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 
 	ret = wait_event_timeout(pipe->wq, pipe->state == VSP1_PIPELINE_STOPPED,
@@ -576,6 +577,7 @@ static void vsp1_video_frame_end(struct vsp1_pipeline *pipe,
 
 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 {
+	enum vsp1_pipeline_state state;
 	unsigned long flags;
 	unsigned int i;
 
@@ -591,11 +593,13 @@ void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 
 	spin_lock_irqsave(&pipe->irqlock, flags);
 
+	state = pipe->state;
+	pipe->state = VSP1_PIPELINE_STOPPED;
+
 	/* If a stop has been requested, mark the pipeline as stopped and
 	 * return.
 	 */
-	if (pipe->state == VSP1_PIPELINE_STOPPING) {
-		pipe->state = VSP1_PIPELINE_STOPPED;
+	if (state == VSP1_PIPELINE_STOPPING) {
 		wake_up(&pipe->wq);
 		goto done;
 	}