int fimc_is_video_close(struct fimc_is_video_ctx *vctx)
{
	int ret = 0;
	u32 video_type = vctx->type;
	struct fimc_is_queue *q_src, *q_dst;

	BUG_ON(!vctx);

	q_src = &vctx->q_src;
	q_dst = &vctx->q_dst;

	switch (video_type) {
	case FIMC_IS_VIDEO_TYPE_OUTPUT:
		BUG_ON(!q_src->vbq);
		fimc_is_queue_close(q_src);
		vb2_queue_release(q_src->vbq);
		kfree(q_src->vbq);
		break;
	case FIMC_IS_VIDEO_TYPE_CAPTURE:
		BUG_ON(!q_dst->vbq);
		fimc_is_queue_close(q_dst);
		vb2_queue_release(q_dst->vbq);
		kfree(q_dst->vbq);
		break;
	case FIMC_IS_VIDEO_TYPE_M2M:
		BUG_ON(!q_src->vbq);
		BUG_ON(!q_dst->vbq);
		fimc_is_queue_close(q_src);
		vb2_queue_release(q_src->vbq);
		fimc_is_queue_close(q_dst);
		vb2_queue_release(q_dst->vbq);
		kfree(q_src->vbq);
		kfree(q_dst->vbq);
		break;
	default:
		merr("invalid type(%d)", vctx, video_type);
		ret = -EINVAL;
		break;
	}

	/*
	 * vb2 release can call stop callback
	 * not if video node is not stream off
	 */
	vctx->device = NULL;

	return ret;
}
int fimc_is_video_close(struct fimc_is_video_ctx *vctx)
{
	int ret = 0;
	struct fimc_is_video *video;
	struct fimc_is_queue *queue;

	BUG_ON(!vctx);
	BUG_ON(!GET_VIDEO(vctx));

	video = GET_VIDEO(vctx);
	queue = GET_QUEUE(vctx);

	if (vctx->state < BIT(FIMC_IS_VIDEO_OPEN)) {
		mverr("already close(%lX)", vctx, video, vctx->state);
		return -ENOENT;
	}

	fimc_is_queue_close(queue);
	vb2_queue_release(queue->vbq);
	kfree(queue->vbq);

	/*
	 * vb2 release can call stop callback
	 * not if video node is not stream off
	 */
	vctx->device = NULL;
	vctx->state = BIT(FIMC_IS_VIDEO_CLOSE);

	return ret;
}