Commit | Line | Data |
---|---|---|
1dbae815 TL |
1 | /* |
2 | * linux/arch/arm/mach-omap2/devices.c | |
3 | * | |
4 | * OMAP2 platform device setup/initialization | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | */ | |
2f8163ba | 11 | #include <linux/gpio.h> |
1dbae815 TL |
12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | |
14 | #include <linux/platform_device.h> | |
fced80c7 | 15 | #include <linux/io.h> |
917fa280 | 16 | #include <linux/clk.h> |
f2ce6231 | 17 | #include <linux/err.h> |
1a5d8190 | 18 | #include <linux/slab.h> |
ad8dfac6 | 19 | #include <linux/of.h> |
484202f4 | 20 | #include <linux/pinctrl/machine.h> |
1dbae815 | 21 | |
1dbae815 TL |
22 | #include <asm/mach-types.h> |
23 | #include <asm/mach/map.h> | |
24 | ||
45c3eb7d | 25 | #include <linux/omap-dma.h> |
2a296c8f | 26 | |
ee0839c2 | 27 | #include "iomap.h" |
2a296c8f | 28 | #include "omap_hwmod.h" |
25c7d49e | 29 | #include "omap_device.h" |
1dbae815 | 30 | |
7d7e1eba TL |
31 | #include "soc.h" |
32 | #include "common.h" | |
4896e394 | 33 | #include "mux.h" |
4814ced5 | 34 | #include "control.h" |
576e5bda | 35 | #include "display.h" |
4896e394 | 36 | |
0abcf618 | 37 | #define L3_MODULES_MAX_LEN 12 |
a4dc616a | 38 | #define L3_MODULES 3 |
0abcf618 | 39 | |
40 | static int __init omap3_l3_init(void) | |
41 | { | |
0abcf618 | 42 | struct omap_hwmod *oh; |
3528c58e | 43 | struct platform_device *pdev; |
0abcf618 | 44 | char oh_name[L3_MODULES_MAX_LEN]; |
45 | ||
46 | /* | |
47 | * To avoid code running on other OMAPs in | |
48 | * multi-omap builds | |
49 | */ | |
aa25729c | 50 | if (!(cpu_is_omap34xx()) || of_have_populated_dt()) |
0abcf618 | 51 | return -ENODEV; |
52 | ||
eeb3711b | 53 | snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); |
0abcf618 | 54 | |
55 | oh = omap_hwmod_lookup(oh_name); | |
56 | ||
57 | if (!oh) | |
58 | pr_err("could not look up %s\n", oh_name); | |
59 | ||
c1d1cd59 | 60 | pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); |
0abcf618 | 61 | |
3528c58e | 62 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); |
0abcf618 | 63 | |
e44be50c | 64 | return PTR_ERR_OR_ZERO(pdev); |
0abcf618 | 65 | } |
b76c8b19 | 66 | omap_postcore_initcall(omap3_l3_init); |
0abcf618 | 67 | |
9b6553cd | 68 | static inline void omap_init_sti(void) {} |
9b6553cd | 69 | |
646e3ed1 | 70 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) |
ed7eb9d9 | 71 | |
2203747c | 72 | #include <linux/platform_data/spi-omap2-mcspi.h> |
ed7eb9d9 | 73 | |
9cf793f9 | 74 | static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) |
af41a12f | 75 | { |
3528c58e | 76 | struct platform_device *pdev; |
1a5d8190 C |
77 | char *name = "omap2_mcspi"; |
78 | struct omap2_mcspi_platform_config *pdata; | |
79 | static int spi_num; | |
80 | struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; | |
81 | ||
82 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | |
83 | if (!pdata) { | |
84 | pr_err("Memory allocation for McSPI device failed\n"); | |
85 | return -ENOMEM; | |
86 | } | |
af41a12f | 87 | |
1a5d8190 C |
88 | pdata->num_cs = mcspi_attrib->num_chipselect; |
89 | switch (oh->class->rev) { | |
90 | case OMAP2_MCSPI_REV: | |
91 | case OMAP3_MCSPI_REV: | |
92 | pdata->regs_offset = 0; | |
93 | break; | |
94 | case OMAP4_MCSPI_REV: | |
95 | pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; | |
96 | break; | |
97 | default: | |
98 | pr_err("Invalid McSPI Revision value\n"); | |
e0feca89 | 99 | kfree(pdata); |
1a5d8190 C |
100 | return -EINVAL; |
101 | } | |
af41a12f | 102 | |
1a5d8190 | 103 | spi_num++; |
c1d1cd59 | 104 | pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); |
3528c58e | 105 | WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", |
1a5d8190 C |
106 | name, oh->name); |
107 | kfree(pdata); | |
108 | return 0; | |
af41a12f | 109 | } |
af41a12f TL |
110 | |
111 | static void omap_init_mcspi(void) | |
112 | { | |
1a5d8190 | 113 | omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); |
ed7eb9d9 JY |
114 | } |
115 | ||
116 | #else | |
117 | static inline void omap_init_mcspi(void) {} | |
118 | #endif | |
119 | ||
4848d460 PW |
120 | /** |
121 | * omap_init_rng - bind the RNG hwmod to the RNG omap_device | |
122 | * | |
123 | * Bind the RNG hwmod to the RNG omap_device. No return value. | |
124 | */ | |
125 | static void omap_init_rng(void) | |
126 | { | |
127 | struct omap_hwmod *oh; | |
128 | struct platform_device *pdev; | |
129 | ||
130 | oh = omap_hwmod_lookup("rng"); | |
131 | if (!oh) | |
132 | return; | |
133 | ||
c1d1cd59 | 134 | pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); |
4848d460 PW |
135 | WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); |
136 | } | |
88341334 | 137 | |
26f88e6e | 138 | static void __init omap_init_sham(void) |
646e3ed1 | 139 | { |
8c7bb573 MG |
140 | struct omap_hwmod *oh; |
141 | struct platform_device *pdev; | |
142 | ||
143 | oh = omap_hwmod_lookup("sham"); | |
144 | if (!oh) | |
145 | return; | |
146 | ||
147 | pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); | |
148 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); | |
646e3ed1 | 149 | } |
646e3ed1 | 150 | |
14ae5564 | 151 | static void __init omap_init_aes(void) |
b744c679 | 152 | { |
77e2fd84 MG |
153 | struct omap_hwmod *oh; |
154 | struct platform_device *pdev; | |
155 | ||
156 | oh = omap_hwmod_lookup("aes"); | |
157 | if (!oh) | |
158 | return; | |
159 | ||
160 | pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); | |
161 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); | |
b744c679 DK |
162 | } |
163 | ||
d8874665 TL |
164 | /*-------------------------------------------------------------------------*/ |
165 | ||
b227358d VH |
166 | #if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ |
167 | defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) | |
168 | #if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) | |
169 | static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = { | |
170 | }; | |
171 | #else | |
172 | static struct resource omap_vout_resource[2] = { | |
173 | }; | |
174 | #endif | |
175 | ||
176 | static struct platform_device omap_vout_device = { | |
177 | .name = "omap_vout", | |
178 | .num_resources = ARRAY_SIZE(omap_vout_resource), | |
179 | .resource = &omap_vout_resource[0], | |
180 | .id = -1, | |
181 | }; | |
576e5bda AT |
182 | |
183 | int __init omap_init_vout(void) | |
b227358d | 184 | { |
576e5bda | 185 | return platform_device_register(&omap_vout_device); |
b227358d VH |
186 | } |
187 | #else | |
576e5bda | 188 | int __init omap_init_vout(void) { return 0; } |
b227358d VH |
189 | #endif |
190 | ||
1dbae815 TL |
191 | /*-------------------------------------------------------------------------*/ |
192 | ||
193 | static int __init omap2_init_devices(void) | |
194 | { | |
484202f4 MP |
195 | /* Enable dummy states for those platforms without pinctrl support */ |
196 | if (!of_have_populated_dt()) | |
197 | pinctrl_provide_dummies(); | |
198 | ||
efcf1e50 | 199 | /* If dtb is there, the devices will be created dynamically */ |
259bd6ce | 200 | if (!of_have_populated_dt()) { |
f2e6a0a9 PU |
201 | /* |
202 | * please keep these calls, and their implementations above, | |
203 | * in alphabetical order so they're easier to sort through. | |
204 | */ | |
efcf1e50 | 205 | omap_init_mcspi(); |
114d7a8b | 206 | omap_init_sham(); |
53335acc | 207 | omap_init_aes(); |
674ee08f | 208 | omap_init_rng(); |
259bd6ce | 209 | } |
9b6553cd | 210 | omap_init_sti(); |
1dbae815 TL |
211 | |
212 | return 0; | |
213 | } | |
b76c8b19 | 214 | omap_arch_initcall(omap2_init_devices); |
a8612809 TL |
215 | |
216 | static int __init omap_gpmc_init(void) | |
217 | { | |
218 | struct omap_hwmod *oh; | |
219 | struct platform_device *pdev; | |
220 | char *oh_name = "gpmc"; | |
221 | ||
222 | /* | |
223 | * if the board boots up with a populated DT, do not | |
224 | * manually add the device from this initcall | |
225 | */ | |
226 | if (of_have_populated_dt()) | |
227 | return -ENODEV; | |
228 | ||
229 | oh = omap_hwmod_lookup(oh_name); | |
230 | if (!oh) { | |
231 | pr_err("Could not look up %s\n", oh_name); | |
232 | return -ENODEV; | |
233 | } | |
234 | ||
235 | pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); | |
236 | WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); | |
237 | ||
e44be50c | 238 | return PTR_ERR_OR_ZERO(pdev); |
a8612809 TL |
239 | } |
240 | omap_postcore_initcall(omap_gpmc_init); |