[media] rcar_vin: helper function for streaming stop
The code that tests that capture from a stream has stopped is presently insufficient and the potential for a race condition exists where frame capture may generate an interrupt between requesting the capture process halt and freeing buffers. This patch refactors code out of rcar_vin_videobuf_release() and into rcar_vin_wait_stop_streaming(), and ensures there are calls in places where we need to know that capturing has finished. Signed-off-by: Ian Molton <ian.molton@codethink.co.uk> Signed-off-by: William Towle <william.towle@codethink.co.uk> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
650b1815ff
commit
4abec46833
|
@ -804,6 +804,28 @@ error:
|
|||
vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for capture to stop and all in-flight buffers to be finished with by
|
||||
* the video hardware. This must be called under &priv->lock
|
||||
*
|
||||
*/
|
||||
static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
|
||||
{
|
||||
while (priv->state != STOPPED) {
|
||||
/* issue stop if running */
|
||||
if (priv->state == RUNNING)
|
||||
rcar_vin_request_capture_stop(priv);
|
||||
|
||||
/* wait until capturing has been stopped */
|
||||
if (priv->state == STOPPING) {
|
||||
priv->request_to_stop = true;
|
||||
spin_unlock_irq(&priv->lock);
|
||||
wait_for_completion(&priv->capture_stop);
|
||||
spin_lock_irq(&priv->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
|
||||
{
|
||||
struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
|
||||
|
@ -823,20 +845,8 @@ static void rcar_vin_videobuf_release(struct vb2_buffer *vb)
|
|||
}
|
||||
|
||||
if (buf_in_use) {
|
||||
while (priv->state != STOPPED) {
|
||||
rcar_vin_wait_stop_streaming(priv);
|
||||
|
||||
/* issue stop if running */
|
||||
if (priv->state == RUNNING)
|
||||
rcar_vin_request_capture_stop(priv);
|
||||
|
||||
/* wait until capturing has been stopped */
|
||||
if (priv->state == STOPPING) {
|
||||
priv->request_to_stop = true;
|
||||
spin_unlock_irq(&priv->lock);
|
||||
wait_for_completion(&priv->capture_stop);
|
||||
spin_lock_irq(&priv->lock);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Capturing has now stopped. The buffer we have been asked
|
||||
* to release could be any of the current buffers in use, so
|
||||
|
@ -870,8 +880,11 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
|
|||
struct list_head *buf_head, *tmp;
|
||||
|
||||
spin_lock_irq(&priv->lock);
|
||||
|
||||
rcar_vin_wait_stop_streaming(priv);
|
||||
list_for_each_safe(buf_head, tmp, &priv->capture)
|
||||
list_del_init(buf_head);
|
||||
|
||||
spin_unlock_irq(&priv->lock);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue