From 3d362c8dbe6d6ab0b4595740229a4d24a49a9a0d Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 27 Jul 2016 14:27:43 +0800 Subject: [PATCH] iommu/rockchip: active and inactive count should be in pairs if attach failed Change-Id: Ic2362814695d135c68ce2db1aec7b71bfcb28dd0 Signed-off-by: Simon --- drivers/iommu/rk-iommu.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/rk-iommu.c b/drivers/iommu/rk-iommu.c index d63bb6f54d64..a55345d497e4 100644 --- a/drivers/iommu/rk-iommu.c +++ b/drivers/iommu/rk-iommu.c @@ -701,17 +701,14 @@ static int rockchip_iommu_enable(struct iommu_drvdata *data, unsigned int pgtabl spin_lock_irqsave(&data->data_lock, flags); if (!rockchip_set_iommu_active(data)) { - if (WARN_ON(pgtable != data->pgtable)) { + if (WARN_ON(pgtable != data->pgtable)) ret = -EBUSY; - rockchip_set_iommu_inactive(data); - } else { + else ret = 1; - } - spin_unlock_irqrestore(&data->data_lock, flags); dev_info(data->iommu, "(%s) Already enabled\n", data->dbgname); - return ret; + goto enable_out; } for (i = 0; i < data->num_res_mem; i++) { @@ -719,15 +716,16 @@ static int rockchip_iommu_enable(struct iommu_drvdata *data, unsigned int pgtabl if (!ret) { dev_info(data->iommu, "(%s), %s failed\n", data->dbgname, __func__); - spin_unlock_irqrestore(&data->data_lock, flags); - return -EBUSY; + ret = -EBUSY; + goto enable_out; } if (!strstr(data->dbgname, "isp")) { if (!rockchip_iommu_reset(data->res_bases[i], data->dbgname)) { - spin_unlock_irqrestore(&data->data_lock, flags); - return -ENOENT; + rockchip_iommu_disable_stall(data->res_bases[i]); + ret = -ENOENT; + goto enable_out; } } @@ -744,22 +742,28 @@ static int rockchip_iommu_enable(struct iommu_drvdata *data, unsigned int pgtabl ret = rockchip_iommu_enable_paging(data->res_bases[i]); if (!ret) { - spin_unlock_irqrestore(&data->data_lock, flags); dev_info(data->iommu, "(%s), %s failed\n", data->dbgname, __func__); - return -EBUSY; + rockchip_iommu_disable_stall(data->res_bases[i]); + ret = -EBUSY; + goto enable_out; } rockchip_iommu_disable_stall(data->res_bases[i]); } data->pgtable = pgtable; + spin_unlock_irqrestore(&data->data_lock, flags); dev_dbg(data->iommu,"(%s) Enabled\n", data->dbgname); + return 0; + +enable_out: + rockchip_set_iommu_inactive(data); spin_unlock_irqrestore(&data->data_lock, flags); - return 0; + return ret; } int rockchip_iommu_tlb_invalidate_global(struct device *dev) -- 2.34.1