diff options
-rw-r--r-- | arch/arm/mach-omap2/omap-iommu.c | 5 | ||||
-rw-r--r-- | drivers/iommu/omap-iommu.c | 42 |
2 files changed, 43 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index f6daae821ebb..f1fab5684a24 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/of.h> | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
@@ -58,6 +59,10 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused) | |||
58 | 59 | ||
59 | static int __init omap_iommu_init(void) | 60 | static int __init omap_iommu_init(void) |
60 | { | 61 | { |
62 | /* If dtb is there, the devices will be created dynamically */ | ||
63 | if (of_have_populated_dt()) | ||
64 | return -ENODEV; | ||
65 | |||
61 | return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL); | 66 | return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL); |
62 | } | 67 | } |
63 | /* must be ready before omap3isp is probed */ | 68 | /* must be ready before omap3isp is probed */ |
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 217952b993e1..eb73ef2b6fa9 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
26 | #include <linux/of.h> | ||
27 | #include <linux/of_iommu.h> | ||
28 | #include <linux/of_irq.h> | ||
26 | 29 | ||
27 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
28 | 31 | ||
@@ -936,17 +939,39 @@ static int omap_iommu_probe(struct platform_device *pdev) | |||
936 | struct omap_iommu *obj; | 939 | struct omap_iommu *obj; |
937 | struct resource *res; | 940 | struct resource *res; |
938 | struct iommu_platform_data *pdata = pdev->dev.platform_data; | 941 | struct iommu_platform_data *pdata = pdev->dev.platform_data; |
942 | struct device_node *of = pdev->dev.of_node; | ||
939 | 943 | ||
940 | obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL); | 944 | obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL); |
941 | if (!obj) | 945 | if (!obj) |
942 | return -ENOMEM; | 946 | return -ENOMEM; |
943 | 947 | ||
944 | obj->nr_tlb_entries = pdata->nr_tlb_entries; | 948 | if (of) { |
945 | obj->name = pdata->name; | 949 | obj->name = dev_name(&pdev->dev); |
950 | obj->nr_tlb_entries = 32; | ||
951 | err = of_property_read_u32(of, "ti,#tlb-entries", | ||
952 | &obj->nr_tlb_entries); | ||
953 | if (err && err != -EINVAL) | ||
954 | return err; | ||
955 | if (obj->nr_tlb_entries != 32 && obj->nr_tlb_entries != 8) | ||
956 | return -EINVAL; | ||
957 | /* | ||
958 | * da_start and da_end are needed for omap-iovmm, so hardcode | ||
959 | * these values as used by OMAP3 ISP - the only user for | ||
960 | * omap-iovmm | ||
961 | */ | ||
962 | obj->da_start = 0; | ||
963 | obj->da_end = 0xfffff000; | ||
964 | } else { | ||
965 | obj->nr_tlb_entries = pdata->nr_tlb_entries; | ||
966 | obj->name = pdata->name; | ||
967 | obj->da_start = pdata->da_start; | ||
968 | obj->da_end = pdata->da_end; | ||
969 | } | ||
970 | if (obj->da_end <= obj->da_start) | ||
971 | return -EINVAL; | ||
972 | |||
946 | obj->dev = &pdev->dev; | 973 | obj->dev = &pdev->dev; |
947 | obj->ctx = (void *)obj + sizeof(*obj); | 974 | obj->ctx = (void *)obj + sizeof(*obj); |
948 | obj->da_start = pdata->da_start; | ||
949 | obj->da_end = pdata->da_end; | ||
950 | 975 | ||
951 | spin_lock_init(&obj->iommu_lock); | 976 | spin_lock_init(&obj->iommu_lock); |
952 | mutex_init(&obj->mmap_lock); | 977 | mutex_init(&obj->mmap_lock); |
@@ -987,11 +1012,20 @@ static int omap_iommu_remove(struct platform_device *pdev) | |||
987 | return 0; | 1012 | return 0; |
988 | } | 1013 | } |
989 | 1014 | ||
1015 | static struct of_device_id omap_iommu_of_match[] = { | ||
1016 | { .compatible = "ti,omap2-iommu" }, | ||
1017 | { .compatible = "ti,omap4-iommu" }, | ||
1018 | { .compatible = "ti,dra7-iommu" }, | ||
1019 | {}, | ||
1020 | }; | ||
1021 | MODULE_DEVICE_TABLE(of, omap_iommu_of_match); | ||
1022 | |||
990 | static struct platform_driver omap_iommu_driver = { | 1023 | static struct platform_driver omap_iommu_driver = { |
991 | .probe = omap_iommu_probe, | 1024 | .probe = omap_iommu_probe, |
992 | .remove = omap_iommu_remove, | 1025 | .remove = omap_iommu_remove, |
993 | .driver = { | 1026 | .driver = { |
994 | .name = "omap-iommu", | 1027 | .name = "omap-iommu", |
1028 | .of_match_table = of_match_ptr(omap_iommu_of_match), | ||
995 | }, | 1029 | }, |
996 | }; | 1030 | }; |
997 | 1031 | ||