aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-11-14 05:08:09 -0500
committerJoerg Roedel <jroedel@suse.de>2016-11-14 11:11:59 -0500
commit92798b4566b1adcf2e259b3116c38553fe655852 (patch)
tree3a480018da6242a66dcdbe938877a5897b29e831
parent47a574fffca10244b7085196e7c0d2dc34eaa6df (diff)
iommu/exynos: Set master device once on boot
To avoid possible races, set master device pointer in each SYSMMU controller once on boot. Suspend/resume callbacks now properly relies on the configured iommu domain to enable or disable SYSMMU controller. While changing the code, also update the sleep debug messages and make them conditional. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/exynos-iommu.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 45a7c6bab9b3..52ded8461a74 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -638,10 +638,12 @@ static int exynos_sysmmu_suspend(struct device *dev)
638 struct sysmmu_drvdata *data = dev_get_drvdata(dev); 638 struct sysmmu_drvdata *data = dev_get_drvdata(dev);
639 struct device *master = data->master; 639 struct device *master = data->master;
640 640
641 dev_dbg(dev, "suspend\n");
642 if (master) { 641 if (master) {
643 __sysmmu_disable(data);
644 pm_runtime_put(dev); 642 pm_runtime_put(dev);
643 if (data->domain) {
644 dev_dbg(data->sysmmu, "saving state\n");
645 __sysmmu_disable(data);
646 }
645 } 647 }
646 return 0; 648 return 0;
647} 649}
@@ -651,10 +653,12 @@ static int exynos_sysmmu_resume(struct device *dev)
651 struct sysmmu_drvdata *data = dev_get_drvdata(dev); 653 struct sysmmu_drvdata *data = dev_get_drvdata(dev);
652 struct device *master = data->master; 654 struct device *master = data->master;
653 655
654 dev_dbg(dev, "resume\n");
655 if (master) { 656 if (master) {
656 pm_runtime_get_sync(dev); 657 pm_runtime_get_sync(dev);
657 __sysmmu_enable(data); 658 if (data->domain) {
659 dev_dbg(data->sysmmu, "restoring state\n");
660 __sysmmu_enable(data);
661 }
658 } 662 }
659 return 0; 663 return 0;
660} 664}
@@ -768,7 +772,6 @@ static void exynos_iommu_domain_free(struct iommu_domain *iommu_domain)
768 __sysmmu_disable(data); 772 __sysmmu_disable(data);
769 data->pgtable = 0; 773 data->pgtable = 0;
770 data->domain = NULL; 774 data->domain = NULL;
771 data->master = NULL;
772 list_del_init(&data->domain_node); 775 list_del_init(&data->domain_node);
773 } 776 }
774 777
@@ -810,7 +813,6 @@ static void exynos_iommu_detach_device(struct iommu_domain *iommu_domain,
810 spin_lock_irqsave(&domain->lock, flags); 813 spin_lock_irqsave(&domain->lock, flags);
811 list_for_each_entry_safe(data, next, &domain->clients, domain_node) { 814 list_for_each_entry_safe(data, next, &domain->clients, domain_node) {
812 __sysmmu_disable(data); 815 __sysmmu_disable(data);
813 data->master = NULL;
814 data->pgtable = 0; 816 data->pgtable = 0;
815 data->domain = NULL; 817 data->domain = NULL;
816 list_del_init(&data->domain_node); 818 list_del_init(&data->domain_node);
@@ -844,7 +846,6 @@ static int exynos_iommu_attach_device(struct iommu_domain *iommu_domain,
844 data->domain = domain; 846 data->domain = domain;
845 pm_runtime_get_sync(data->sysmmu); 847 pm_runtime_get_sync(data->sysmmu);
846 __sysmmu_enable(data); 848 __sysmmu_enable(data);
847 data->master = dev;
848 849
849 spin_lock_irqsave(&domain->lock, flags); 850 spin_lock_irqsave(&domain->lock, flags);
850 list_add_tail(&data->domain_node, &domain->clients); 851 list_add_tail(&data->domain_node, &domain->clients);
@@ -1231,6 +1232,7 @@ static int exynos_iommu_of_xlate(struct device *dev,
1231 } 1232 }
1232 1233
1233 list_add_tail(&data->owner_node, &owner->controllers); 1234 list_add_tail(&data->owner_node, &owner->controllers);
1235 data->master = dev;
1234 return 0; 1236 return 0;
1235} 1237}
1236 1238