aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/davinci/vpif_display.c
diff options
context:
space:
mode:
authorLad, Prabhakar <prabhakar.csengg@gmail.com>2014-05-16 09:33:09 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-23 18:01:30 -0400
commit54a445a41bac7c320ee00afa633fe869428697c4 (patch)
tree073d01c3ed306e543f015cebae7b231ac367aec6 /drivers/media/platform/davinci/vpif_display.c
parentd10ed5c1906e708e6a9fc26e9dd25b479b5439e9 (diff)
[media] media: davinci: vpif_display: 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/vpif_display.c')
-rw-r--r--drivers/media/platform/davinci/vpif_display.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 8bb9f022d225..1a17a455b44f 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -196,26 +196,16 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
196 struct channel_obj *ch = vb2_get_drv_priv(vq); 196 struct channel_obj *ch = vb2_get_drv_priv(vq);
197 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; 197 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
198 struct vpif_params *vpif = &ch->vpifparams; 198 struct vpif_params *vpif = &ch->vpifparams;
199 unsigned long addr = 0; 199 struct vpif_disp_buffer *buf, *tmp;
200 unsigned long flags; 200 unsigned long addr, flags;
201 int ret; 201 int ret;
202 202
203 spin_lock_irqsave(&common->irqlock, flags); 203 spin_lock_irqsave(&common->irqlock, flags);
204 204
205 /* Get the next frame from the buffer queue */
206 common->next_frm = common->cur_frm =
207 list_entry(common->dma_queue.next,
208 struct vpif_disp_buffer, list);
209
210 list_del(&common->cur_frm->list);
211 spin_unlock_irqrestore(&common->irqlock, flags);
212 /* Mark state of the current frame to active */
213 common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
214
215 /* Initialize field_id and started member */ 205 /* Initialize field_id and started member */
216 ch->field_id = 0; 206 ch->field_id = 0;
217 common->started = 1; 207 common->started = 1;
218 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0); 208
219 /* Calculate the offset for Y and C data in the buffer */ 209 /* Calculate the offset for Y and C data in the buffer */
220 vpif_calculate_offsets(ch); 210 vpif_calculate_offsets(ch);
221 211
@@ -225,7 +215,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
225 || (!ch->vpifparams.std_info.frm_fmt 215 || (!ch->vpifparams.std_info.frm_fmt
226 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { 216 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
227 vpif_err("conflict in field format and std format\n"); 217 vpif_err("conflict in field format and std format\n");
228 return -EINVAL; 218 ret = -EINVAL;
219 goto err;
229 } 220 }
230 221
231 /* clock settings */ 222 /* clock settings */
@@ -234,17 +225,28 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
234 ycmux_mode, ch->vpifparams.std_info.hd_sd); 225 ycmux_mode, ch->vpifparams.std_info.hd_sd);
235 if (ret < 0) { 226 if (ret < 0) {
236 vpif_err("can't set clock\n"); 227 vpif_err("can't set clock\n");
237 return ret; 228 goto err;
238 } 229 }
239 } 230 }
240 231
241 /* set the parameters and addresses */ 232 /* set the parameters and addresses */
242 ret = vpif_set_video_params(vpif, ch->channel_id + 2); 233 ret = vpif_set_video_params(vpif, ch->channel_id + 2);
243 if (ret < 0) 234 if (ret < 0)
244 return ret; 235 goto err;
245 236
246 common->started = ret; 237 common->started = ret;
247 vpif_config_addr(ch, ret); 238 vpif_config_addr(ch, ret);
239 /* Get the next frame from the buffer queue */
240 common->next_frm = common->cur_frm =
241 list_entry(common->dma_queue.next,
242 struct vpif_disp_buffer, list);
243
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
249 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
248 common->set_addr((addr + common->ytop_off), 250 common->set_addr((addr + common->ytop_off),
249 (addr + common->ybtm_off), 251 (addr + common->ybtm_off),
250 (addr + common->ctop_off), 252 (addr + common->ctop_off),
@@ -271,6 +273,14 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
271 } 273 }
272 274
273 return 0; 275 return 0;
276
277err:
278 list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
279 list_del(&buf->list);
280 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
281 }
282
283 return ret;
274} 284}
275 285
276/* abort streaming and wait for last buffer */ 286/* abort streaming and wait for last buffer */