Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
omap-iommu.c
Go to the documentation of this file.
1 /*
2  * omap iommu: omap device registration
3  *
4  * Copyright (C) 2008-2009 Nokia Corporation
5  *
6  * Written by Hiroshi DOYU <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 
16 #include <plat/iommu.h>
17 
18 #include "soc.h"
19 #include "common.h"
20 
21 struct iommu_device {
23  int irq;
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)
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)
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 {
102  int i, err;
103  struct resource res[] = {
104  { .flags = IORESOURCE_MEM },
105  { .flags = IORESOURCE_IRQ },
106  };
107 
108  if (cpu_is_omap34xx()) {
109  devices = omap3_devices;
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 
119  for (i = 0; i < num_iommu_devices; i++) {
120  struct platform_device *pdev;
121  const struct iommu_device *d = &devices[i];
122 
123  pdev = platform_device_alloc("omap-iommu", i);
124  if (!pdev) {
125  err = -ENOMEM;
126  goto err_out;
127  }
128 
129  res[0].start = d->base;
130  res[0].end = d->base + MMU_REG_SIZE - 1;
131  res[1].start = res[1].end = d->irq;
132 
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;
147 
148 err_out:
149  while (i--)
150  platform_device_put(omap_iommu_pdev[i]);
151  return err;
152 }
153 /* must be ready before omap3isp is probed */
154 subsys_initcall(omap_iommu_init);
155 
156 static void __exit omap_iommu_exit(void)
157 {
158  int i;
159 
160  for (i = 0; i < num_iommu_devices; i++)
161  platform_device_unregister(omap_iommu_pdev[i]);
162 }
163 module_exit(omap_iommu_exit);
164 
165 MODULE_AUTHOR("Hiroshi DOYU");
166 MODULE_DESCRIPTION("omap iommu: omap device registration");
167 MODULE_LICENSE("GPL v2");