diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap-iommu.c')
-rw-r--r-- | arch/arm/mach-omap2/omap-iommu.c | 167 |
1 files changed, 37 insertions, 130 deletions
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index a6a4ff8744b7..7642fc4672c1 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c | |||
@@ -12,153 +12,60 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/err.h> | ||
16 | #include <linux/slab.h> | ||
15 | 17 | ||
16 | #include <linux/platform_data/iommu-omap.h> | 18 | #include <linux/platform_data/iommu-omap.h> |
19 | #include <plat/omap_hwmod.h> | ||
20 | #include <plat/omap_device.h> | ||
17 | 21 | ||
18 | #include "soc.h" | 22 | static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused) |
19 | #include "common.h" | ||
20 | |||
21 | struct iommu_device { | ||
22 | resource_size_t base; | ||
23 | int irq; | ||
24 | struct iommu_platform_data pdata; | ||
25 | struct resource res[2]; | ||
26 | }; | ||
27 | static struct iommu_device *devices; | ||
28 | static int num_iommu_devices; | ||
29 | |||
30 | #ifdef CONFIG_ARCH_OMAP3 | ||
31 | static struct iommu_device omap3_devices[] = { | ||
32 | { | ||
33 | .base = 0x480bd400, | ||
34 | .irq = 24 + OMAP_INTC_START, | ||
35 | .pdata = { | ||
36 | .name = "isp", | ||
37 | .nr_tlb_entries = 8, | ||
38 | .clk_name = "cam_ick", | ||
39 | .da_start = 0x0, | ||
40 | .da_end = 0xFFFFF000, | ||
41 | }, | ||
42 | }, | ||
43 | #if defined(CONFIG_OMAP_IOMMU_IVA2) | ||
44 | { | ||
45 | .base = 0x5d000000, | ||
46 | .irq = 28 + OMAP_INTC_START, | ||
47 | .pdata = { | ||
48 | .name = "iva2", | ||
49 | .nr_tlb_entries = 32, | ||
50 | .clk_name = "iva2_ck", | ||
51 | .da_start = 0x11000000, | ||
52 | .da_end = 0xFFFFF000, | ||
53 | }, | ||
54 | }, | ||
55 | #endif | ||
56 | }; | ||
57 | #define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices) | ||
58 | static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; | ||
59 | #else | ||
60 | #define omap3_devices NULL | ||
61 | #define NR_OMAP3_IOMMU_DEVICES 0 | ||
62 | #define omap3_iommu_pdev NULL | ||
63 | #endif | ||
64 | |||
65 | #ifdef CONFIG_ARCH_OMAP4 | ||
66 | static struct iommu_device omap4_devices[] = { | ||
67 | { | ||
68 | .base = OMAP4_MMU1_BASE, | ||
69 | .irq = 100 + OMAP44XX_IRQ_GIC_START, | ||
70 | .pdata = { | ||
71 | .name = "ducati", | ||
72 | .nr_tlb_entries = 32, | ||
73 | .clk_name = "ipu_fck", | ||
74 | .da_start = 0x0, | ||
75 | .da_end = 0xFFFFF000, | ||
76 | }, | ||
77 | }, | ||
78 | { | ||
79 | .base = OMAP4_MMU2_BASE, | ||
80 | .irq = 28 + OMAP44XX_IRQ_GIC_START, | ||
81 | .pdata = { | ||
82 | .name = "tesla", | ||
83 | .nr_tlb_entries = 32, | ||
84 | .clk_name = "dsp_fck", | ||
85 | .da_start = 0x0, | ||
86 | .da_end = 0xFFFFF000, | ||
87 | }, | ||
88 | }, | ||
89 | }; | ||
90 | #define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices) | ||
91 | static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES]; | ||
92 | #else | ||
93 | #define omap4_devices NULL | ||
94 | #define NR_OMAP4_IOMMU_DEVICES 0 | ||
95 | #define omap4_iommu_pdev NULL | ||
96 | #endif | ||
97 | |||
98 | static struct platform_device **omap_iommu_pdev; | ||
99 | |||
100 | static int __init omap_iommu_init(void) | ||
101 | { | 23 | { |
102 | int i, err; | 24 | struct platform_device *pdev; |
103 | struct resource res[] = { | 25 | struct iommu_platform_data *pdata; |
104 | { .flags = IORESOURCE_MEM }, | 26 | struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr; |
105 | { .flags = IORESOURCE_IRQ }, | 27 | static int i; |
106 | }; | 28 | |
29 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
30 | if (!pdata) | ||
31 | return -ENOMEM; | ||
32 | |||
33 | pdata->name = oh->name; | ||
34 | pdata->nr_tlb_entries = a->nr_tlb_entries; | ||
35 | pdata->da_start = a->da_start; | ||
36 | pdata->da_end = a->da_end; | ||
37 | |||
38 | if (oh->rst_lines_cnt == 1) { | ||
39 | pdata->reset_name = oh->rst_lines->name; | ||
40 | pdata->assert_reset = omap_device_assert_hardreset; | ||
41 | pdata->deassert_reset = omap_device_deassert_hardreset; | ||
42 | } | ||
107 | 43 | ||
108 | if (cpu_is_omap34xx()) { | 44 | pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata), |
109 | devices = omap3_devices; | 45 | NULL, 0, 0); |
110 | omap_iommu_pdev = omap3_iommu_pdev; | ||
111 | num_iommu_devices = NR_OMAP3_IOMMU_DEVICES; | ||
112 | } else if (cpu_is_omap44xx()) { | ||
113 | devices = omap4_devices; | ||
114 | omap_iommu_pdev = omap4_iommu_pdev; | ||
115 | num_iommu_devices = NR_OMAP4_IOMMU_DEVICES; | ||
116 | } else | ||
117 | return -ENODEV; | ||
118 | 46 | ||
119 | for (i = 0; i < num_iommu_devices; i++) { | 47 | kfree(pdata); |
120 | struct platform_device *pdev; | ||
121 | const struct iommu_device *d = &devices[i]; | ||
122 | 48 | ||
123 | pdev = platform_device_alloc("omap-iommu", i); | 49 | if (IS_ERR(pdev)) { |
124 | if (!pdev) { | 50 | pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev)); |
125 | err = -ENOMEM; | 51 | return PTR_ERR(pdev); |
126 | goto err_out; | 52 | } |
127 | } | ||
128 | 53 | ||
129 | res[0].start = d->base; | 54 | i++; |
130 | res[0].end = d->base + MMU_REG_SIZE - 1; | ||
131 | res[1].start = res[1].end = d->irq; | ||
132 | 55 | ||
133 | err = platform_device_add_resources(pdev, res, | ||
134 | ARRAY_SIZE(res)); | ||
135 | if (err) | ||
136 | goto err_out; | ||
137 | err = platform_device_add_data(pdev, &d->pdata, | ||
138 | sizeof(d->pdata)); | ||
139 | if (err) | ||
140 | goto err_out; | ||
141 | err = platform_device_add(pdev); | ||
142 | if (err) | ||
143 | goto err_out; | ||
144 | omap_iommu_pdev[i] = pdev; | ||
145 | } | ||
146 | return 0; | 56 | return 0; |
57 | } | ||
147 | 58 | ||
148 | err_out: | 59 | static int __init omap_iommu_init(void) |
149 | while (i--) | 60 | { |
150 | platform_device_put(omap_iommu_pdev[i]); | 61 | return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL); |
151 | return err; | ||
152 | } | 62 | } |
153 | /* must be ready before omap3isp is probed */ | 63 | /* must be ready before omap3isp is probed */ |
154 | subsys_initcall(omap_iommu_init); | 64 | subsys_initcall(omap_iommu_init); |
155 | 65 | ||
156 | static void __exit omap_iommu_exit(void) | 66 | static void __exit omap_iommu_exit(void) |
157 | { | 67 | { |
158 | int i; | 68 | /* Do nothing */ |
159 | |||
160 | for (i = 0; i < num_iommu_devices; i++) | ||
161 | platform_device_unregister(omap_iommu_pdev[i]); | ||
162 | } | 69 | } |
163 | module_exit(omap_iommu_exit); | 70 | module_exit(omap_iommu_exit); |
164 | 71 | ||