Commit ca657b28 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] marvell-ccic: correctly requeue buffers

If start_streaming fails or stop_streaming is called, then all queued
buffers need to be given back to vb2.

This prevents vb2 from calling WARN_ON when it detects that this is not
done correctly.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarJonathan Corbet <corbet@lwn.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 53423429
...@@ -607,6 +607,7 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame) ...@@ -607,6 +607,7 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) { if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) {
cam->frame_state.delivered++; cam->frame_state.delivered++;
cam->vb_bufs[frame] = NULL;
mcam_buffer_done(cam, frame, &buf->vb_buf); mcam_buffer_done(cam, frame, &buf->vb_buf);
} }
mcam_set_contig_buffer(cam, frame); mcam_set_contig_buffer(cam, frame);
...@@ -1106,6 +1107,30 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb) ...@@ -1106,6 +1107,30 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb)
mcam_read_setup(cam); mcam_read_setup(cam);
} }
static void mcam_vb_requeue_bufs(struct vb2_queue *vq,
enum vb2_buffer_state state)
{
struct mcam_camera *cam = vb2_get_drv_priv(vq);
struct mcam_vb_buffer *buf, *node;
unsigned long flags;
unsigned i;
spin_lock_irqsave(&cam->dev_lock, flags);
list_for_each_entry_safe(buf, node, &cam->buffers, queue) {
vb2_buffer_done(&buf->vb_buf, state);
list_del(&buf->queue);
}
for (i = 0; i < MAX_DMA_BUFS; i++) {
buf = cam->vb_bufs[i];
if (buf) {
vb2_buffer_done(&buf->vb_buf, state);
cam->vb_bufs[i] = NULL;
}
}
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
/* /*
* These need to be called with the mutex held from vb2 * These need to be called with the mutex held from vb2
*/ */
...@@ -1113,9 +1138,10 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -1113,9 +1138,10 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
{ {
struct mcam_camera *cam = vb2_get_drv_priv(vq); struct mcam_camera *cam = vb2_get_drv_priv(vq);
unsigned int frame; unsigned int frame;
int ret;
if (cam->state != S_IDLE) { if (cam->state != S_IDLE) {
INIT_LIST_HEAD(&cam->buffers); mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED);
return -EINVAL; return -EINVAL;
} }
cam->frame_state.frames = 0; cam->frame_state.frames = 0;
...@@ -1141,13 +1167,15 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) ...@@ -1141,13 +1167,15 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
for (frame = 0; frame < cam->nbufs; frame++) for (frame = 0; frame < cam->nbufs; frame++)
clear_bit(CF_FRAME_SOF0 + frame, &cam->flags); clear_bit(CF_FRAME_SOF0 + frame, &cam->flags);
return mcam_read_setup(cam); ret = mcam_read_setup(cam);
if (ret)
mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED);
return ret;
} }
static void mcam_vb_stop_streaming(struct vb2_queue *vq) static void mcam_vb_stop_streaming(struct vb2_queue *vq)
{ {
struct mcam_camera *cam = vb2_get_drv_priv(vq); struct mcam_camera *cam = vb2_get_drv_priv(vq);
unsigned long flags;
cam_dbg(cam, "stop_streaming: %d frames, %d singles, %d delivered\n", cam_dbg(cam, "stop_streaming: %d frames, %d singles, %d delivered\n",
cam->frame_state.frames, cam->frame_state.singles, cam->frame_state.frames, cam->frame_state.singles,
...@@ -1170,9 +1198,7 @@ static void mcam_vb_stop_streaming(struct vb2_queue *vq) ...@@ -1170,9 +1198,7 @@ static void mcam_vb_stop_streaming(struct vb2_queue *vq)
* VB2 reclaims the buffers, so we need to forget * VB2 reclaims the buffers, so we need to forget
* about them. * about them.
*/ */
spin_lock_irqsave(&cam->dev_lock, flags); mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_ERROR);
INIT_LIST_HEAD(&cam->buffers);
spin_unlock_irqrestore(&cam->dev_lock, flags);
} }
...@@ -1786,7 +1812,6 @@ int mccic_register(struct mcam_camera *cam) ...@@ -1786,7 +1812,6 @@ int mccic_register(struct mcam_camera *cam)
mcam_set_config_needed(cam, 1); mcam_set_config_needed(cam, 1);
cam->pix_format = mcam_def_pix_format; cam->pix_format = mcam_def_pix_format;
cam->mbus_code = mcam_def_mbus_code; cam->mbus_code = mcam_def_mbus_code;
INIT_LIST_HEAD(&cam->buffers);
mcam_ctlr_init(cam); mcam_ctlr_init(cam);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment