diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-03-01 11:43:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-04-17 06:44:02 -0400 |
commit | 994d5375a246c6585d2a6751d568cc86e89aef34 (patch) | |
tree | 79708fd709ce5c304b0bfc7d2beaf755d9b02778 /drivers/media/video/omap3isp | |
parent | b5feda91c1c3510f54720dd8f086653af230a0e1 (diff) |
[media] omap3isp: isp: Reset the ISP when the pipeline can't be stopped
When a failure to stop a module in the pipeline is detected, the only
way to recover is to reset the ISP. However, as other users can be using
a different pipeline with other modules, the ISP can't be reset
synchronously with the error detection.
Mark the ISP as needing a reset when a failure to stop a pipeline is
detected, and reset the ISP when the last user releases the last
reference to the ISP.
Modify the omap3isp_pipeline_set_stream() function to record the new ISP
pipeline state only when no error occurs, except when stopping the
pipeline in which case the pipeline is still marked as stopped.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/omap3isp')
-rw-r--r-- | drivers/media/video/omap3isp/isp.c | 14 | ||||
-rw-r--r-- | drivers/media/video/omap3isp/isp.h | 1 |
2 files changed, 13 insertions, 2 deletions
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 7d68b109d32f..f380f09b119c 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -872,6 +872,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) | |||
872 | } | 872 | } |
873 | } | 873 | } |
874 | 874 | ||
875 | if (failure < 0) | ||
876 | isp->needs_reset = true; | ||
877 | |||
875 | return failure; | 878 | return failure; |
876 | } | 879 | } |
877 | 880 | ||
@@ -884,7 +887,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) | |||
884 | * single-shot or continuous mode. | 887 | * single-shot or continuous mode. |
885 | * | 888 | * |
886 | * Return 0 if successful, or the return value of the failed video::s_stream | 889 | * Return 0 if successful, or the return value of the failed video::s_stream |
887 | * operation otherwise. | 890 | * operation otherwise. The pipeline state is not updated when the operation |
891 | * fails, except when stopping the pipeline. | ||
888 | */ | 892 | */ |
889 | int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | 893 | int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, |
890 | enum isp_pipeline_stream_state state) | 894 | enum isp_pipeline_stream_state state) |
@@ -895,7 +899,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | |||
895 | ret = isp_pipeline_disable(pipe); | 899 | ret = isp_pipeline_disable(pipe); |
896 | else | 900 | else |
897 | ret = isp_pipeline_enable(pipe, state); | 901 | ret = isp_pipeline_enable(pipe, state); |
898 | pipe->stream_state = state; | 902 | |
903 | if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED) | ||
904 | pipe->stream_state = state; | ||
899 | 905 | ||
900 | return ret; | 906 | return ret; |
901 | } | 907 | } |
@@ -1481,6 +1487,10 @@ void omap3isp_put(struct isp_device *isp) | |||
1481 | if (--isp->ref_count == 0) { | 1487 | if (--isp->ref_count == 0) { |
1482 | isp_disable_interrupts(isp); | 1488 | isp_disable_interrupts(isp); |
1483 | isp_save_ctx(isp); | 1489 | isp_save_ctx(isp); |
1490 | if (isp->needs_reset) { | ||
1491 | isp_reset(isp); | ||
1492 | isp->needs_reset = false; | ||
1493 | } | ||
1484 | isp_disable_clocks(isp); | 1494 | isp_disable_clocks(isp); |
1485 | } | 1495 | } |
1486 | mutex_unlock(&isp->isp_mutex); | 1496 | mutex_unlock(&isp->isp_mutex); |
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h index cf5214e95a92..5f87645565b8 100644 --- a/drivers/media/video/omap3isp/isp.h +++ b/drivers/media/video/omap3isp/isp.h | |||
@@ -262,6 +262,7 @@ struct isp_device { | |||
262 | /* ISP Obj */ | 262 | /* ISP Obj */ |
263 | spinlock_t stat_lock; /* common lock for statistic drivers */ | 263 | spinlock_t stat_lock; /* common lock for statistic drivers */ |
264 | struct mutex isp_mutex; /* For handling ref_count field */ | 264 | struct mutex isp_mutex; /* For handling ref_count field */ |
265 | bool needs_reset; | ||
265 | int has_context; | 266 | int has_context; |
266 | int ref_count; | 267 | int ref_count; |
267 | unsigned int autoidle; | 268 | unsigned int autoidle; |