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

Commit 9dc22ca5 authored by Aditya Jonnalagadda's avatar Aditya Jonnalagadda
Browse files

msm: camera: Maintain buffer queue in isp buf manager



we encountered a problem where we try to free one
of buffers from previous ion session and this results
in a BUG_ON because of mismatch of ion_handles.

Inorder to avoid this we maintain a queue for
all the buffers during prepare buf and we unprepare only
if the buffer is present in this queue.

Change-Id: I02d37a94d55bb199fbcfeed9bbbfa471a70850ac
Signed-off-by: default avatarAditya Jonnalagadda <ajonnala@codeaurora.org>
parent 4db175e5
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -122,6 +122,8 @@ static int msm_isp_prepare_v4l2_buf(struct msm_isp_buf_mgr *buf_mgr,
{
	int i, rc = -1;
	struct msm_isp_buffer_mapped_info *mapped_info;
	struct buffer_cmd *buf_pending = NULL;

	for (i = 0; i < v4l2_buf->length; i++) {
		mapped_info = &buf_info->mapped_info[i];
		mapped_info->handle =
@@ -144,6 +146,15 @@ static int msm_isp_prepare_v4l2_buf(struct msm_isp_buf_mgr *buf_mgr,
		mapped_info->paddr += v4l2_buf->m.planes[i].data_offset;
		CDBG("%s: plane: %d addr:%lu\n",
			__func__, i, mapped_info->paddr);

		buf_pending = kzalloc(sizeof(struct buffer_cmd), GFP_ATOMIC);
		if (!buf_pending) {
			pr_err("No free memory for buf_pending\n");
			return rc;
		}

		buf_pending->mapped_info = mapped_info;
		list_add_tail(&buf_pending->list, &buf_mgr->buffer_q);
	}
	buf_info->num_planes = v4l2_buf->length;
	return 0;
@@ -163,11 +174,26 @@ static void msm_isp_unprepare_v4l2_buf(
{
	int i;
	struct msm_isp_buffer_mapped_info *mapped_info;
	struct buffer_cmd *buf_pending = NULL;

	for (i = 0; i < buf_info->num_planes; i++) {
		mapped_info = &buf_info->mapped_info[i];
		ion_unmap_iommu(buf_mgr->client, mapped_info->handle,

		list_for_each_entry(buf_pending, &buf_mgr->buffer_q, list) {
			if (!buf_pending)
				break;

			if (buf_pending->mapped_info == mapped_info) {
				ion_unmap_iommu(buf_mgr->client,
					mapped_info->handle,
					buf_mgr->iommu_domain_num, 0);
				ion_free(buf_mgr->client, mapped_info->handle);

				list_del_init(&buf_pending->list);
				kfree(buf_pending);
				break;
			}
		}
	}
	return;
}
@@ -725,6 +751,7 @@ static void msm_isp_release_all_bufq(
		if (!bufq->bufq_handle)
			continue;
		msm_isp_buf_unprepare(buf_mgr, bufq->bufq_handle);

		kfree(bufq->bufs);
		msm_isp_free_buf_handle(buf_mgr, bufq->bufq_handle);
	}
@@ -773,9 +800,10 @@ static int msm_isp_init_isp_buf_mgr(
		pr_err("Invalid buffer queue number\n");
		return rc;
	}

	CDBG("%s: E\n", __func__);

	msm_isp_attach_ctx(buf_mgr);
	INIT_LIST_HEAD(&buf_mgr->buffer_q);
	buf_mgr->num_buf_q = num_buf_q;
	buf_mgr->bufq =
		kzalloc(sizeof(struct msm_isp_bufq) * num_buf_q,
+7 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -56,6 +56,11 @@ struct msm_isp_buffer_mapped_info {
	struct ion_handle *handle;
};

struct buffer_cmd {
	struct list_head list;
	struct msm_isp_buffer_mapped_info *mapped_info;
};

struct msm_isp_buffer {
	/*Common Data structure*/
	int num_planes;
@@ -153,6 +158,7 @@ struct msm_isp_buf_mgr {

	int num_iommu_ctx;
	struct device *iommu_ctx[2];
	struct list_head buffer_q;
};

int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,