aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Vaussard <florian.vaussard@epfl.ch>2014-02-28 15:42:36 -0500
committerJoerg Roedel <joro@8bytes.org>2014-03-04 11:01:57 -0500
commit3c92748df9941ff8f5be4655a04812ff4d0c7eeb (patch)
treecfcd9c51f714c5b0fe318f81b8e96c6fa983d1fc
parenta8689f65de5a8c3e47bf29c2550dfebe0744e077 (diff)
iommu/omap: Add devicetree support
As OMAP2+ is moving to a full DT boot for all SoC families, commit 7ce93f3 "ARM: OMAP2+: Fix more missing data for omap3.dtsi file" adds basic DT bits for OMAP3. But the driver is not yet converted, so this will not work and driver will not be probed. Convert it! The legacy boot mode is still supported until OMAP3 is converted to DT-boot only. Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch> [s-anna@ti.com: dev_name adaptation and improved error checking] Signed-off-by: Suman Anna <s-anna@ti.com> [tony@atomide.com: Ack for arch/arm/*omap* parts] Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Joerg Roedel <joro@8bytes.org>
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c5
-rw-r--r--drivers/iommu/omap-iommu.c42
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
59static int __init omap_iommu_init(void) 60static 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
1015static 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};
1021MODULE_DEVICE_TABLE(of, omap_iommu_of_match);
1022
990static struct platform_driver omap_iommu_driver = { 1023static 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