mirror of
https://github.com/torvalds/linux
synced 2024-09-23 04:49:22 +00:00
[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>
This commit is contained in:
parent
b5feda91c1
commit
994d5375a2
|
@ -872,6 +872,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (failure < 0)
|
||||||
|
isp->needs_reset = true;
|
||||||
|
|
||||||
return failure;
|
return failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,7 +887,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
|
||||||
* single-shot or continuous mode.
|
* single-shot or continuous mode.
|
||||||
*
|
*
|
||||||
* Return 0 if successful, or the return value of the failed video::s_stream
|
* Return 0 if successful, or the return value of the failed video::s_stream
|
||||||
* operation otherwise.
|
* operation otherwise. The pipeline state is not updated when the operation
|
||||||
|
* fails, except when stopping the pipeline.
|
||||||
*/
|
*/
|
||||||
int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
|
int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
|
||||||
enum isp_pipeline_stream_state state)
|
enum isp_pipeline_stream_state state)
|
||||||
|
@ -895,7 +899,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
|
||||||
ret = isp_pipeline_disable(pipe);
|
ret = isp_pipeline_disable(pipe);
|
||||||
else
|
else
|
||||||
ret = isp_pipeline_enable(pipe, state);
|
ret = isp_pipeline_enable(pipe, state);
|
||||||
pipe->stream_state = state;
|
|
||||||
|
if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)
|
||||||
|
pipe->stream_state = state;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1481,6 +1487,10 @@ void omap3isp_put(struct isp_device *isp)
|
||||||
if (--isp->ref_count == 0) {
|
if (--isp->ref_count == 0) {
|
||||||
isp_disable_interrupts(isp);
|
isp_disable_interrupts(isp);
|
||||||
isp_save_ctx(isp);
|
isp_save_ctx(isp);
|
||||||
|
if (isp->needs_reset) {
|
||||||
|
isp_reset(isp);
|
||||||
|
isp->needs_reset = false;
|
||||||
|
}
|
||||||
isp_disable_clocks(isp);
|
isp_disable_clocks(isp);
|
||||||
}
|
}
|
||||||
mutex_unlock(&isp->isp_mutex);
|
mutex_unlock(&isp->isp_mutex);
|
||||||
|
|
|
@ -262,6 +262,7 @@ struct isp_device {
|
||||||
/* ISP Obj */
|
/* ISP Obj */
|
||||||
spinlock_t stat_lock; /* common lock for statistic drivers */
|
spinlock_t stat_lock; /* common lock for statistic drivers */
|
||||||
struct mutex isp_mutex; /* For handling ref_count field */
|
struct mutex isp_mutex; /* For handling ref_count field */
|
||||||
|
bool needs_reset;
|
||||||
int has_context;
|
int has_context;
|
||||||
int ref_count;
|
int ref_count;
|
||||||
unsigned int autoidle;
|
unsigned int autoidle;
|
||||||
|
|
Loading…
Reference in a new issue