msm: mdss: protect iommu refcount with mutex for mdp3

On mdp3 targets iommu refcount is not properly protected
by mutex lock. This is causing iommu to be detached while
hardware is fetching the data from the iommu mapped
address leading to SNOC errors. Add mutex lock while
using the iommu refcounts to fix the issue.

Change-Id: Ife59791b08b123f6b60d3ffa6d8061839244934c
Signed-off-by: Shivaraj Shetty <shivaraj@codeaurora.org>
This commit is contained in:
Shivaraj Shetty 2015-04-18 00:11:22 +05:30 committed by David Keitel
parent 8c89959820
commit 0db2c5fa4f

View file

@ -726,11 +726,9 @@ int mdp3_iommu_attach(int context)
if (context >= MDP3_IOMMU_CTX_MAX) if (context >= MDP3_IOMMU_CTX_MAX)
return -EINVAL; return -EINVAL;
mutex_lock(&mdp3_res->iommu_lock);
context_map = mdp3_res->iommu_contexts + context; context_map = mdp3_res->iommu_contexts + context;
if (context_map->attached) { if (context_map->attached) {
pr_warn("mdp iommu already attached\n"); pr_warn("mdp iommu already attached\n");
mutex_unlock(&mdp3_res->iommu_lock);
return 0; return 0;
} }
@ -743,7 +741,6 @@ int mdp3_iommu_attach(int context)
} }
context_map->attached = true; context_map->attached = true;
mutex_unlock(&mdp3_res->iommu_lock);
return 0; return 0;
} }
@ -756,11 +753,9 @@ int mdp3_iommu_dettach(int context)
context >= MDP3_IOMMU_CTX_MAX) context >= MDP3_IOMMU_CTX_MAX)
return -EINVAL; return -EINVAL;
mutex_lock(&mdp3_res->iommu_lock);
context_map = mdp3_res->iommu_contexts + context; context_map = mdp3_res->iommu_contexts + context;
if (!context_map->attached) { if (!context_map->attached) {
pr_warn("mdp iommu not attached\n"); pr_warn("mdp iommu not attached\n");
mutex_unlock(&mdp3_res->iommu_lock);
return 0; return 0;
} }
@ -768,7 +763,6 @@ int mdp3_iommu_dettach(int context)
iommu_detach_device(domain_map->domain, context_map->ctx); iommu_detach_device(domain_map->domain, context_map->ctx);
context_map->attached = false; context_map->attached = false;
mutex_unlock(&mdp3_res->iommu_lock);
return 0; return 0;
} }
@ -966,7 +960,11 @@ static void mdp3_res_deinit(void)
mdp3_hw = &mdp3_res->mdp3_hw; mdp3_hw = &mdp3_res->mdp3_hw;
mdp3_bus_scale_unregister(); mdp3_bus_scale_unregister();
mutex_lock(&mdp3_res->iommu_lock);
mdp3_iommu_dettach(MDP3_IOMMU_CTX_MDP_0); mdp3_iommu_dettach(MDP3_IOMMU_CTX_MDP_0);
mutex_unlock(&mdp3_res->iommu_lock);
mdp3_iommu_deinit(); mdp3_iommu_deinit();
if (!IS_ERR_OR_NULL(mdp3_res->ion_client)) if (!IS_ERR_OR_NULL(mdp3_res->ion_client))
@ -1366,6 +1364,7 @@ int mdp3_iommu_enable()
{ {
int i, rc = 0; int i, rc = 0;
mutex_lock(&mdp3_res->iommu_lock);
if (mdp3_res->iommu_ref_cnt == 0) { if (mdp3_res->iommu_ref_cnt == 0) {
for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++) { for (i = 0; i < MDP3_IOMMU_CTX_MAX; i++) {
rc = mdp3_iommu_attach(i); rc = mdp3_iommu_attach(i);
@ -1379,6 +1378,7 @@ int mdp3_iommu_enable()
if (!rc) if (!rc)
mdp3_res->iommu_ref_cnt++; mdp3_res->iommu_ref_cnt++;
mutex_unlock(&mdp3_res->iommu_lock);
return rc; return rc;
} }
@ -1387,6 +1387,7 @@ int mdp3_iommu_disable()
{ {
int i, rc = 0; int i, rc = 0;
mutex_lock(&mdp3_res->iommu_lock);
if (mdp3_res->iommu_ref_cnt) { if (mdp3_res->iommu_ref_cnt) {
mdp3_res->iommu_ref_cnt--; mdp3_res->iommu_ref_cnt--;
if (mdp3_res->iommu_ref_cnt == 0) { if (mdp3_res->iommu_ref_cnt == 0) {
@ -1396,6 +1397,7 @@ int mdp3_iommu_disable()
} else { } else {
pr_err("iommu ref count unbalanced\n"); pr_err("iommu ref count unbalanced\n");
} }
mutex_unlock(&mdp3_res->iommu_lock);
return rc; return rc;
} }