diff options
author | Sakari Ailus <sakari.ailus@iki.fi> | 2011-10-10 16:05:24 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 07:49:56 -0400 |
commit | da39257f0bc5a5780735abb8c8031e20a701d49a (patch) | |
tree | 278c27dad7eea0674c2ff732be1042eada3ba44e /drivers | |
parent | b0cd79ed987c7b362a2e1a339ce9959192dc2f52 (diff) |
[media] omap3isp: Assume media_entity_pipeline_start may fail
Since media_entity_pipeline_start() now does link validation, it may
actually fail. Perform the error handling.
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/omap3isp/ispvideo.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index 5e55477f120d..b6c407c37502 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c | |||
@@ -1002,14 +1002,16 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1002 | pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); | 1002 | pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); |
1003 | pipe->max_rate = pipe->l3_ick; | 1003 | pipe->max_rate = pipe->l3_ick; |
1004 | 1004 | ||
1005 | media_entity_pipeline_start(&video->video.entity, &pipe->pipe); | 1005 | ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe); |
1006 | if (ret < 0) | ||
1007 | goto err_pipeline_start; | ||
1006 | 1008 | ||
1007 | /* Verify that the currently configured format matches the output of | 1009 | /* Verify that the currently configured format matches the output of |
1008 | * the connected subdev. | 1010 | * the connected subdev. |
1009 | */ | 1011 | */ |
1010 | ret = isp_video_check_format(video, vfh); | 1012 | ret = isp_video_check_format(video, vfh); |
1011 | if (ret < 0) | 1013 | if (ret < 0) |
1012 | goto error; | 1014 | goto err_check_format; |
1013 | 1015 | ||
1014 | video->bpl_padding = ret; | 1016 | video->bpl_padding = ret; |
1015 | video->bpl_value = vfh->format.fmt.pix.bytesperline; | 1017 | video->bpl_value = vfh->format.fmt.pix.bytesperline; |
@@ -1026,7 +1028,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1026 | } else { | 1028 | } else { |
1027 | if (far_end == NULL) { | 1029 | if (far_end == NULL) { |
1028 | ret = -EPIPE; | 1030 | ret = -EPIPE; |
1029 | goto error; | 1031 | goto err_check_format; |
1030 | } | 1032 | } |
1031 | 1033 | ||
1032 | state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT; | 1034 | state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT; |
@@ -1037,7 +1039,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1037 | /* Validate the pipeline and update its state. */ | 1039 | /* Validate the pipeline and update its state. */ |
1038 | ret = isp_video_validate_pipeline(pipe); | 1040 | ret = isp_video_validate_pipeline(pipe); |
1039 | if (ret < 0) | 1041 | if (ret < 0) |
1040 | goto error; | 1042 | goto err_check_format; |
1041 | 1043 | ||
1042 | pipe->error = false; | 1044 | pipe->error = false; |
1043 | 1045 | ||
@@ -1059,7 +1061,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1059 | 1061 | ||
1060 | ret = omap3isp_video_queue_streamon(&vfh->queue); | 1062 | ret = omap3isp_video_queue_streamon(&vfh->queue); |
1061 | if (ret < 0) | 1063 | if (ret < 0) |
1062 | goto error; | 1064 | goto err_check_format; |
1063 | 1065 | ||
1064 | /* In sensor-to-memory mode, the stream can be started synchronously | 1066 | /* In sensor-to-memory mode, the stream can be started synchronously |
1065 | * to the stream on command. In memory-to-memory mode, it will be | 1067 | * to the stream on command. In memory-to-memory mode, it will be |
@@ -1069,32 +1071,34 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) | |||
1069 | ret = omap3isp_pipeline_set_stream(pipe, | 1071 | ret = omap3isp_pipeline_set_stream(pipe, |
1070 | ISP_PIPELINE_STREAM_CONTINUOUS); | 1072 | ISP_PIPELINE_STREAM_CONTINUOUS); |
1071 | if (ret < 0) | 1073 | if (ret < 0) |
1072 | goto error; | 1074 | goto err_set_stream; |
1073 | spin_lock_irqsave(&video->queue->irqlock, flags); | 1075 | spin_lock_irqsave(&video->queue->irqlock, flags); |
1074 | if (list_empty(&video->dmaqueue)) | 1076 | if (list_empty(&video->dmaqueue)) |
1075 | video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN; | 1077 | video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN; |
1076 | spin_unlock_irqrestore(&video->queue->irqlock, flags); | 1078 | spin_unlock_irqrestore(&video->queue->irqlock, flags); |
1077 | } | 1079 | } |
1078 | 1080 | ||
1079 | error: | 1081 | video->streaming = 1; |
1080 | if (ret < 0) { | 1082 | |
1081 | omap3isp_video_queue_streamoff(&vfh->queue); | 1083 | mutex_unlock(&video->stream_lock); |
1082 | media_entity_pipeline_stop(&video->video.entity); | 1084 | return 0; |
1083 | if (video->isp->pdata->set_constraints) | ||
1084 | video->isp->pdata->set_constraints(video->isp, false); | ||
1085 | /* The DMA queue must be emptied here, otherwise CCDC interrupts | ||
1086 | * that will get triggered the next time the CCDC is powered up | ||
1087 | * will try to access buffers that might have been freed but | ||
1088 | * still present in the DMA queue. This can easily get triggered | ||
1089 | * if the above omap3isp_pipeline_set_stream() call fails on a | ||
1090 | * system with a free-running sensor. | ||
1091 | */ | ||
1092 | INIT_LIST_HEAD(&video->dmaqueue); | ||
1093 | video->queue = NULL; | ||
1094 | } | ||
1095 | 1085 | ||
1096 | if (!ret) | 1086 | err_set_stream: |
1097 | video->streaming = 1; | 1087 | omap3isp_video_queue_streamoff(&vfh->queue); |
1088 | err_check_format: | ||
1089 | media_entity_pipeline_stop(&video->video.entity); | ||
1090 | err_pipeline_start: | ||
1091 | if (video->isp->pdata->set_constraints) | ||
1092 | video->isp->pdata->set_constraints(video->isp, false); | ||
1093 | /* The DMA queue must be emptied here, otherwise CCDC interrupts that | ||
1094 | * will get triggered the next time the CCDC is powered up will try to | ||
1095 | * access buffers that might have been freed but still present in the | ||
1096 | * DMA queue. This can easily get triggered if the above | ||
1097 | * omap3isp_pipeline_set_stream() call fails on a system with a | ||
1098 | * free-running sensor. | ||
1099 | */ | ||
1100 | INIT_LIST_HEAD(&video->dmaqueue); | ||
1101 | video->queue = NULL; | ||
1098 | 1102 | ||
1099 | mutex_unlock(&video->stream_lock); | 1103 | mutex_unlock(&video->stream_lock); |
1100 | return ret; | 1104 | return ret; |