From 5bb0884f842d33316563b962ccf0a226acfcdff5 Mon Sep 17 00:00:00 2001 From: Simon Xue Date: Tue, 25 Feb 2020 14:20:28 +0800 Subject: [PATCH] iommu: rockchip: Introduce flush_iotlb_all to shoot entire tlb once Change-Id: I1ef476fcde1b6d323dd2653dc01e27f9990cc6f5 Signed-off-by: Simon Xue --- drivers/iommu/rockchip-iommu.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 1b1209dd9c07..2747dffe69c9 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -864,6 +864,35 @@ static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova, return unmap_size; } +static void rk_iommu_flush_tlb_all(struct iommu_domain *domain) +{ + struct rk_iommu_domain *rk_domain = to_rk_domain(domain); + struct list_head *pos; + unsigned long flags; + int i; + + spin_lock_irqsave(&rk_domain->iommus_lock, flags); + list_for_each(pos, &rk_domain->iommus) { + struct rk_iommu *iommu; + int ret; + + iommu = list_entry(pos, struct rk_iommu, node); + + ret = pm_runtime_get_if_in_use(iommu->dev); + if (WARN_ON_ONCE(ret < 0)) + continue; + if (ret) { + WARN_ON(clk_bulk_enable(iommu->num_clocks, iommu->clocks)); + for (i = 0; i < iommu->num_mmu; i++) + rk_iommu_write(iommu->bases[i], RK_MMU_COMMAND, + RK_MMU_CMD_ZAP_CACHE); + clk_bulk_disable(iommu->num_clocks, iommu->clocks); + pm_runtime_put(iommu->dev); + } + } + spin_unlock_irqrestore(&rk_domain->iommus_lock, flags); +} + static struct rk_iommu *rk_iommu_from_dev(struct device *dev) { struct rk_iommudata *data = dev->archdata.iommu; @@ -1185,6 +1214,7 @@ static const struct iommu_ops rk_iommu_ops = { .detach_dev = rk_iommu_detach_device, .map = rk_iommu_map, .unmap = rk_iommu_unmap, + .flush_iotlb_all = rk_iommu_flush_tlb_all, .add_device = rk_iommu_add_device, .remove_device = rk_iommu_remove_device, .iova_to_phys = rk_iommu_iova_to_phys,