From aa34284b75bffaa3f75c6e96158676bbf5de8936 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 7 Apr 2015 17:50:00 +0800 Subject: [PATCH] rk3368: iommu: expose iommu tlb invalidate operation to owner Signed-off-by: Simon --- drivers/iommu/rockchip-iommu.c | 28 ++++++++++++++++++++++++++++ drivers/iommu/rockchip-iommu.h | 5 +++++ drivers/iommu/rockchip-iovmm.c | 7 +++++++ include/linux/rockchip-iovmm.h | 7 ++++++- 4 files changed, 46 insertions(+), 1 deletion(-) mode change 100755 => 100644 drivers/iommu/rockchip-iommu.h mode change 100755 => 100644 drivers/iommu/rockchip-iovmm.c mode change 100755 => 100644 include/linux/rockchip-iovmm.h diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index be089f10ecd8..da9492073f70 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -754,6 +754,34 @@ static int rockchip_iommu_enable(struct iommu_drvdata *data, unsigned int pgtabl return 0; } +int rockchip_iommu_tlb_invalidate_global(struct device *dev) +{ + unsigned long flags; + struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu); + int ret; + + spin_lock_irqsave(&data->data_lock, flags); + + if (rockchip_is_iommu_active(data)) { + int i; + + for (i = 0; i < data->num_res_mem; i++) { + ret = rockchip_iommu_zap_tlb(data->res_bases[i]); + if (ret) + dev_err(dev->archdata.iommu, "(%s) %s failed\n", + data->dbgname, __func__); + } + } else { + dev_dbg(dev->archdata.iommu, "(%s) Disabled. Skipping invalidating TLB.\n", + data->dbgname); + ret = -1; + } + + spin_unlock_irqrestore(&data->data_lock, flags); + + return ret; +} + int rockchip_iommu_tlb_invalidate(struct device *dev) { unsigned long flags; diff --git a/drivers/iommu/rockchip-iommu.h b/drivers/iommu/rockchip-iommu.h old mode 100755 new mode 100644 index e470115e9ffe..d206b555f4d6 --- a/drivers/iommu/rockchip-iommu.h +++ b/drivers/iommu/rockchip-iommu.h @@ -79,12 +79,17 @@ static inline int rockchip_init_iovmm(struct device *iommu, * This function flush all TLB entry in iommu */ int rockchip_iommu_tlb_invalidate(struct device *owner); +int rockchip_iommu_tlb_invalidate_global(struct device *owner); #else /* CONFIG_ROCKCHIP_IOMMU */ static inline int rockchip_iommu_tlb_invalidate(struct device *owner) { return -1; } +static int rockchip_iommu_tlb_invalidate_global(struct device *owner) +{ + return -1; +} #endif diff --git a/drivers/iommu/rockchip-iovmm.c b/drivers/iommu/rockchip-iovmm.c old mode 100755 new mode 100644 index 3be00729a36c..193e0b5e8657 --- a/drivers/iommu/rockchip-iovmm.c +++ b/drivers/iommu/rockchip-iovmm.c @@ -30,6 +30,13 @@ static struct rk_vm_region *find_region(struct rk_iovmm *vmm, dma_addr_t iova) return NULL; } +int rockchip_iovmm_invalidate_tlb(struct device *dev) +{ + int ret = rockchip_iommu_tlb_invalidate_global(dev); + + return ret; +} + void rockchip_iovmm_set_fault_handler(struct device *dev, rockchip_iommu_fault_handler_t handler) { diff --git a/include/linux/rockchip-iovmm.h b/include/linux/rockchip-iovmm.h old mode 100755 new mode 100644 index 3a7dae2f9de0..919663457d7b --- a/include/linux/rockchip-iovmm.h +++ b/include/linux/rockchip-iovmm.h @@ -107,7 +107,8 @@ void rockchip_iovmm_set_fault_handler(struct device *dev, * return value: non-zero if the fault is correctly resolved. * zero if the fault is not handled. */ - + +int rockchip_iovmm_invalidate_tlb(struct device *dev); #else static inline int rockchip_iovmm_activate(struct device *dev) { @@ -142,6 +143,10 @@ static inline void rockchip_iovmm_set_fault_handler(struct device *dev, rockchip_iommu_fault_handler_t handler) { } +static inline int rockchip_iovmm_invalidate_tlb(struct device *dev) +{ + return -ENOSYS; +} #endif /* CONFIG_ROCKCHIP_IOVMM */ -- 2.34.1