Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54a445a4 authored by Lad, Prabhakar's avatar Lad, Prabhakar Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarLad, Prabhakar <prabhakar.csengg@gmail.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent d10ed5c1
Loading
Loading
Loading
Loading
+26 −16
Original line number Original line Diff line number Diff line
@@ -196,26 +196,16 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
	struct channel_obj *ch = vb2_get_drv_priv(vq);
	struct channel_obj *ch = vb2_get_drv_priv(vq);
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
	struct vpif_params *vpif = &ch->vpifparams;
	struct vpif_params *vpif = &ch->vpifparams;
	unsigned long addr = 0;
	struct vpif_disp_buffer *buf, *tmp;
	unsigned long flags;
	unsigned long addr, flags;
	int ret;
	int ret;


	spin_lock_irqsave(&common->irqlock, flags);
	spin_lock_irqsave(&common->irqlock, flags);


	/* Get the next frame from the buffer queue */
	common->next_frm = common->cur_frm =
			    list_entry(common->dma_queue.next,
				       struct vpif_disp_buffer, list);

	list_del(&common->cur_frm->list);
	spin_unlock_irqrestore(&common->irqlock, flags);
	/* Mark state of the current frame to active */
	common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;

	/* Initialize field_id and started member */
	/* Initialize field_id and started member */
	ch->field_id = 0;
	ch->field_id = 0;
	common->started = 1;
	common->started = 1;
	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);

	/* Calculate the offset for Y and C data  in the buffer */
	/* Calculate the offset for Y and C data  in the buffer */
	vpif_calculate_offsets(ch);
	vpif_calculate_offsets(ch);


@@ -225,7 +215,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
		|| (!ch->vpifparams.std_info.frm_fmt
		|| (!ch->vpifparams.std_info.frm_fmt
		&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
		&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
		vpif_err("conflict in field format and std format\n");
		vpif_err("conflict in field format and std format\n");
		return -EINVAL;
		ret = -EINVAL;
		goto err;
	}
	}


	/* clock settings */
	/* clock settings */
@@ -234,17 +225,28 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
		ycmux_mode, ch->vpifparams.std_info.hd_sd);
		ycmux_mode, ch->vpifparams.std_info.hd_sd);
		if (ret < 0) {
		if (ret < 0) {
			vpif_err("can't set clock\n");
			vpif_err("can't set clock\n");
			return ret;
			goto err;
		}
		}
	}
	}


	/* set the parameters and addresses */
	/* set the parameters and addresses */
	ret = vpif_set_video_params(vpif, ch->channel_id + 2);
	ret = vpif_set_video_params(vpif, ch->channel_id + 2);
	if (ret < 0)
	if (ret < 0)
		return ret;
		goto err;


	common->started = ret;
	common->started = ret;
	vpif_config_addr(ch, ret);
	vpif_config_addr(ch, ret);
	/* Get the next frame from the buffer queue */
	common->next_frm = common->cur_frm =
			    list_entry(common->dma_queue.next,
				       struct vpif_disp_buffer, list);

	list_del(&common->cur_frm->list);
	spin_unlock_irqrestore(&common->irqlock, flags);
	/* Mark state of the current frame to active */
	common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;

	addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
	common->set_addr((addr + common->ytop_off),
	common->set_addr((addr + common->ytop_off),
			    (addr + common->ybtm_off),
			    (addr + common->ybtm_off),
			    (addr + common->ctop_off),
			    (addr + common->ctop_off),
@@ -271,6 +273,14 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
	}
	}


	return 0;
	return 0;

err:
	list_for_each_entry_safe(buf, tmp, &common->dma_queue, list) {
		list_del(&buf->list);
		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
	}

	return ret;
}
}


/* abort streaming and wait for last buffer */
/* abort streaming and wait for last buffer */