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

Commit b54b34f5 authored by Sreesudhan Ramakrish Ramkumar's avatar Sreesudhan Ramakrish Ramkumar
Browse files

msm: camera: isp: Fix pip camera exit issue



During pip camera exit, iommu_detach is not called due to race
condition and incorrect state check. Add spin lock and proper
condition statement to make sure iommu_attach and iommu_detach
is called once during pip camera open and close respectively.

Change-Id: I5a02fea0659bca1a8742152694a96614a5adbbb8
Signed-off-by: default avatarSreesudhan Ramakrish Ramkumar <srramku@codeaurora.org>
parent 18c43109
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, 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
@@ -959,6 +959,7 @@ static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr,
						__func__, i, rc);
					return -EINVAL;
				}
				buf_mgr->attach_state = MSM_ISP_BUF_MGR_ATTACH;
			}
			buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i]++;
		}
@@ -976,11 +977,11 @@ static int msm_isp_attach_ctx(struct msm_isp_buf_mgr *buf_mgr,
						__func__, i, rc);
					return -EINVAL;
				}
				buf_mgr->attach_state = MSM_ISP_BUF_MGR_ATTACH;
			}
			buf_mgr->attach_ref_cnt[SECURE_MODE][i]++;
		}
	}
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_ATTACH;
	return 0;
}

@@ -988,10 +989,6 @@ static int msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr)
{
	int i;

	if (buf_mgr->attach_state == MSM_ISP_BUF_MGR_DETACH ||
		buf_mgr->open_count)
		return 0;

	if (buf_mgr->secure_enable == NON_SECURE_MODE) {
		/*non secure mode*/
		for (i = 0; i < buf_mgr->num_iommu_ctx; i++) {
@@ -999,6 +996,7 @@ static int msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr)
			if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] == 1) {
				iommu_detach_device(buf_mgr->iommu_domain,
					buf_mgr->iommu_ctx[i]);
				buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;
			}
			if (buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i] > 0)
				--buf_mgr->attach_ref_cnt[NON_SECURE_MODE][i];
@@ -1011,12 +1009,12 @@ static int msm_isp_detach_ctx(struct msm_isp_buf_mgr *buf_mgr)
				iommu_detach_device(
						buf_mgr->iommu_domain_secure,
						buf_mgr->iommu_secure_ctx[i]);
				buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;
			}
			if (buf_mgr->attach_ref_cnt[SECURE_MODE][i] > 0)
				--buf_mgr->attach_ref_cnt[SECURE_MODE][i];
		}
	}
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;
	return 0;
}

@@ -1026,6 +1024,7 @@ int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr,
	struct msm_vfe_smmu_attach_cmd *cmd = arg;
	int rc = 0;
	pr_debug("%s: cmd->security_mode : %d\n", __func__, cmd->security_mode);
	mutex_lock(&buf_mgr->lock);
	if (cmd->iommu_attach_mode == IOMMU_ATTACH) {
		buf_mgr->secure_enable = cmd->security_mode;
		rc = msm_isp_attach_ctx(buf_mgr, cmd);
@@ -1037,6 +1036,7 @@ int msm_isp_smmu_attach(struct msm_isp_buf_mgr *buf_mgr,
		msm_isp_detach_ctx(buf_mgr);

iommu_error:
	mutex_unlock(&buf_mgr->lock);
	return rc;
}

@@ -1046,11 +1046,15 @@ static int msm_isp_init_isp_buf_mgr(
	const char *ctx_name, uint16_t num_buf_q)
{
	int rc = -1;
	if (buf_mgr->open_count++)
	mutex_lock(&buf_mgr->lock);
	if (buf_mgr->open_count++) {
		mutex_unlock(&buf_mgr->lock);
		return 0;
	}

	if (!num_buf_q) {
		pr_err("Invalid buffer queue number\n");
		mutex_unlock(&buf_mgr->lock);
		return rc;
	}
	CDBG("%s: E\n", __func__);
@@ -1067,25 +1071,31 @@ static int msm_isp_init_isp_buf_mgr(
	buf_mgr->client = msm_ion_client_create(ctx_name);
	buf_mgr->buf_handle_cnt = 0;
	buf_mgr->pagefault_debug = 0;
	mutex_unlock(&buf_mgr->lock);
	return 0;
bufq_error:
	mutex_unlock(&buf_mgr->lock);
	return rc;
}

static int msm_isp_deinit_isp_buf_mgr(
	struct msm_isp_buf_mgr *buf_mgr)
{
	mutex_lock(&buf_mgr->lock);
	if (buf_mgr->open_count > 0)
		buf_mgr->open_count--;

	if (buf_mgr->open_count)
	if (buf_mgr->open_count) {
		mutex_unlock(&buf_mgr->lock);
		return 0;
	}
	msm_isp_release_all_bufq(buf_mgr);
	ion_client_destroy(buf_mgr->client);
	kfree(buf_mgr->bufq);
	buf_mgr->num_buf_q = 0;
	buf_mgr->pagefault_debug = 0;
	msm_isp_detach_ctx(buf_mgr);
	mutex_unlock(&buf_mgr->lock);
	return 0;
}

@@ -1213,6 +1223,7 @@ int msm_isp_create_isp_buf_mgr(
	buf_mgr->pagefault_debug = 0;
	buf_mgr->secure_enable = NON_SECURE_MODE;
	buf_mgr->attach_state = MSM_ISP_BUF_MGR_DETACH;
	mutex_init(&buf_mgr->lock);

	for (i = 0; i < MAX_PROTECTION_MODE; i++)
		for (j = 0; j < MAX_IOMMU_CTX; j++)
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, 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
@@ -158,7 +158,6 @@ struct msm_isp_buf_mgr {
	int init_done;
	uint32_t open_count;
	uint32_t pagefault_debug;
	spinlock_t lock;
	uint16_t num_buf_q;
	struct msm_isp_bufq *bufq;

@@ -186,6 +185,7 @@ struct msm_isp_buf_mgr {
	struct device *iommu_secure_ctx[2];
	int attach_ref_cnt[MAX_PROTECTION_MODE][MAX_IOMMU_CTX];
	enum msm_isp_buf_mgr_state attach_state;
	struct mutex lock;
};

int msm_isp_create_isp_buf_mgr(struct msm_isp_buf_mgr *buf_mgr,