From: Janghyuck Kim Date: Fri, 27 May 2016 01:23:56 +0000 (+0900) Subject: [COMMON] exynos/iommu: add suspended state X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=5cd932de53ae822380957be0298ca1042fe9a551;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git [COMMON] exynos/iommu: add suspended state This patch added suspended state that becomes true when sysmmu goes to suspend state. No SFR access is allowed if sysmmu is in suspended. Without suspended state, some operation involving SFR access like tlb invalidation would make external abort because it only checks internal reference count before SFR access, and internal reference count is remained after sysmmu becomes suspend state. Change-Id: I7460e8b0b96de5f46584cc299dc2e659fc34da44 Signed-off-by: Janghyuck Kim --- diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 62ec5882d839..1eb9ba95d72b 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -559,8 +559,10 @@ static int exynos_sysmmu_suspend(struct device *dev) spin_lock_irqsave(&drvdata->lock, flags); if (is_sysmmu_active(drvdata) && - is_sysmmu_runtime_active(drvdata)) + is_sysmmu_runtime_active(drvdata)) { __sysmmu_disable_nocount(drvdata); + drvdata->is_suspended = true; + } spin_unlock_irqrestore(&drvdata->lock, flags); return 0; @@ -572,9 +574,10 @@ static int exynos_sysmmu_resume(struct device *dev) struct sysmmu_drvdata *drvdata = dev_get_drvdata(dev); spin_lock_irqsave(&drvdata->lock, flags); - if (is_sysmmu_active(drvdata) && - is_sysmmu_runtime_active(drvdata)) + if (drvdata->is_suspended) { __sysmmu_enable_nocount(drvdata); + drvdata->is_suspended = false; + } spin_unlock_irqrestore(&drvdata->lock, flags); return 0; diff --git a/drivers/iommu/exynos-iommu.h b/drivers/iommu/exynos-iommu.h index 8350c962bb07..671d0559fd9c 100644 --- a/drivers/iommu/exynos-iommu.h +++ b/drivers/iommu/exynos-iommu.h @@ -207,6 +207,7 @@ struct sysmmu_drvdata { phys_addr_t pgtable; /* assigned page table structure */ int version; /* our version */ struct atomic_notifier_head fault_notifiers; + bool is_suspended; }; struct exynos_vm_region { @@ -275,7 +276,7 @@ static inline bool set_sysmmu_inactive(struct sysmmu_drvdata *data) static inline bool is_sysmmu_active(struct sysmmu_drvdata *data) { - return data->activations > 0; + return !data->is_suspended && data->activations > 0; } static inline void __raw_sysmmu_enable(void __iomem *sfrbase)