diff options
author | Lad, Prabhakar <prabhakar.csengg@gmail.com> | 2014-05-16 09:33:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-23 18:20:54 -0400 |
commit | bebd8d12295dbeedaa9d6b309ed63b7fcd31e0e5 (patch) | |
tree | e030d01bc2ed39aec66cca83caac2b15f34a31d8 /drivers/media/platform/davinci | |
parent | 999ba69bf35c6ab0bdb0bd65cb0dd67cb1b96d99 (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.c | 39 |
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 | |||
313 | err: | ||
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 */ |