From: Simon Date: Wed, 27 Jul 2016 06:27:43 +0000 (+0800) Subject: iommu/rockchip: active and inactive count should be in pairs if attach failed X-Git-Tag: firefly_0821_release~2076 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3d362c8dbe6d6ab0b4595740229a4d24a49a9a0d;p=firefly-linux-kernel-4.4.55.git iommu/rockchip: active and inactive count should be in pairs if attach failed Change-Id: Ic2362814695d135c68ce2db1aec7b71bfcb28dd0 Signed-off-by: Simon --- 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)