aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/davinci
diff options
context:
space:
mode:
authorLad, Prabhakar <prabhakar.csengg@gmail.com>2014-05-16 09:33:35 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-23 18:20:54 -0400
commitbebd8d12295dbeedaa9d6b309ed63b7fcd31e0e5 (patch)
treee030d01bc2ed39aec66cca83caac2b15f34a31d8 /drivers/media/platform/davinci
parent999ba69bf35c6ab0bdb0bd65cb0dd67cb1b96d99 (diff)
[media] media: davinci: vpif_capture: release buffers in case start_streaming() call back fails
this patch adds support to release the buffer by calling vb2_buffer_done(), with state marked as VB2_BUF_STATE_QUEUED if start_streaming() call back fails. Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/davinci')
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 8572efe949c8..fd384d0b0c47 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -231,24 +231,15 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
231 struct channel_obj *ch = vb2_get_drv_priv(vq); 231 struct channel_obj *ch = vb2_get_drv_priv(vq);
232 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 232 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
233 struct vpif_params *vpif = &ch->vpifparams; 233 struct vpif_params *vpif = &ch->vpifparams;
234 unsigned long addr = 0; 234 struct vpif_cap_buffer *buf, *tmp;
235 unsigned long flags; 235 unsigned long addr, flags;
236 int ret; 236 int ret;
237 237
238 spin_lock_irqsave(&common->irqlock, flags); 238 spin_lock_irqsave(&common->irqlock, flags);
239 239
240 /* Get the next frame from the buffer queue */
241 common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
242 struct vpif_cap_buffer, list);
243 /* Remove buffer from the buffer queue */
244 list_del(&common->cur_frm->list);
245 spin_unlock_irqrestore(&common->irqlock, flags);
246 /* Mark state of the current frame to active */
247 common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
248 /* Initialize field_id and started member */ 240 /* Initialize field_id and started member */
249 ch->field_id = 0; 241 ch->field_id = 0;
250 common->started = 1; 242 common->started = 1;
251 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
252 243
253 /* Calculate the offset for Y and C data in the buffer */ 244 /* Calculate the offset for Y and C data in the buffer */
254 vpif_calculate_offsets(ch); 245 vpif_calculate_offsets(ch);
@@ -259,7 +250,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
259 (!vpif->std_info.frm_fmt && 250 (!vpif->std_info.frm_fmt &&
260 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { 251 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
261 vpif_dbg(1, debug, "conflict in field format and std format\n"); 252 vpif_dbg(1, debug, "conflict in field format and std format\n");
262 return -EINVAL; 253 ret = -EINVAL;
254 goto err;
263 } 255 }
264 256
265 /* configure 1 or 2 channel mode */ 257 /* configure 1 or 2 channel mode */
@@ -268,7 +260,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
268 setup_input_channel_mode(vpif->std_info.ycmux_mode); 260 setup_input_channel_mode(vpif->std_info.ycmux_mode);
269 if (ret < 0) { 261 if (ret < 0) {
270 vpif_dbg(1, debug, "can't set vpif channel mode\n"); 262 vpif_dbg(1, debug, "can't set vpif channel mode\n");
271 return ret; 263 goto err;
272 } 264 }
273 } 265 }
274 266
@@ -277,12 +269,23 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
277 269
278 if (ret < 0) { 270 if (ret < 0) {
279 vpif_dbg(1, debug, "can't set video params\n"); 271 vpif_dbg(1, debug, "can't set video params\n");
280 return ret; 272 goto err;
281 } 273 }
282 274
283 common->started = ret; 275 common->started = ret;
284 vpif_config_addr(ch, ret); 276 vpif_config_addr(ch, ret);
285 277
278 /* Get the next frame from the buffer queue */
279 common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
280 struct vpif_cap_buffer, list);
281 /* Remove buffer from the buffer queue */
282 list_del(&common->cur_frm->list);
283 spin_unlock_irqrestore(&common->irqlock, flags);
284 /* Mark state of the current frame to active */
285 common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
286
287 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
288
286 common->set_addr(addr + common->ytop_off, 289 common->set_addr(addr + common->ytop_off,
287 addr + common->ybtm_off, 290 addr + common->ybtm_off,
288 addr + common->ctop_off, 291 addr + common->ctop_off,
@@ -306,6 +309,14 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
306 } 309 }
307 310
308 return 0; 311 return 0;
312
313err:
314 list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
315 list_del(&buf->list);
316 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
317 }
318
319 return ret;
309} 320}
310 321
311/* abort streaming and wait for last buffer */ 322/* abort streaming and wait for last buffer */