iommu/exynos: Add callback for initializing devices from device tree
authorMarek Szyprowski <m.szyprowski@samsung.com>
Tue, 19 May 2015 13:20:37 +0000 (15:20 +0200)
committerJoerg Roedel <jroedel@suse.de>
Fri, 29 May 2015 08:50:08 +0000 (10:50 +0200)
This patch adds implementation of of_xlate callback, which prepares
masters device for attaching to IOMMU. This callback is called during
creating devices from device tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/exynos-iommu.c

index 0fb40ee9d7280d769637ad5ed36e99bb08f879bd..97c41b8ab5d980667667bde15ad1d16105278b65 100644 (file)
@@ -1146,6 +1146,33 @@ static void exynos_iommu_remove_device(struct device *dev)
        iommu_group_remove_device(dev);
 }
 
+static int exynos_iommu_of_xlate(struct device *dev,
+                                struct of_phandle_args *spec)
+{
+       struct exynos_iommu_owner *owner = dev->archdata.iommu;
+       struct platform_device *sysmmu = of_find_device_by_node(spec->np);
+       struct sysmmu_drvdata *data;
+
+       if (!sysmmu)
+               return -ENODEV;
+
+       data = platform_get_drvdata(sysmmu);
+       if (!data)
+               return -ENODEV;
+
+       if (!owner) {
+               owner = kzalloc(sizeof(*owner), GFP_KERNEL);
+               if (!owner)
+                       return -ENOMEM;
+
+               INIT_LIST_HEAD(&owner->controllers);
+               dev->archdata.iommu = owner;
+       }
+
+       list_add_tail(&data->owner_node, &owner->controllers);
+       return 0;
+}
+
 static struct iommu_ops exynos_iommu_ops = {
        .domain_alloc = exynos_iommu_domain_alloc,
        .domain_free = exynos_iommu_domain_free,
@@ -1158,6 +1185,7 @@ static struct iommu_ops exynos_iommu_ops = {
        .add_device = exynos_iommu_add_device,
        .remove_device = exynos_iommu_remove_device,
        .pgsize_bitmap = SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+       .of_xlate = exynos_iommu_of_xlate,
 };
 
 static bool init_done;