1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Legacy platform_data quirks |
4 | * |
5 | * Copyright (C) 2013 Texas Instruments |
6 | */ |
7 | #include <linux/clk.h> |
8 | #include <linux/davinci_emac.h> |
9 | #include <linux/gpio/machine.h> |
10 | #include <linux/gpio/consumer.h> |
11 | #include <linux/init.h> |
12 | #include <linux/kernel.h> |
13 | #include <linux/of_platform.h> |
14 | #include <linux/mmc/card.h> |
15 | #include <linux/mmc/host.h> |
16 | #include <linux/power/smartreflex.h> |
17 | #include <linux/regulator/machine.h> |
18 | #include <linux/regulator/fixed.h> |
19 | |
20 | #include <linux/platform_data/pinctrl-single.h> |
21 | #include <linux/platform_data/hsmmc-omap.h> |
22 | #include <linux/platform_data/iommu-omap.h> |
23 | #include <linux/platform_data/ti-sysc.h> |
24 | #include <linux/platform_data/wkup_m3.h> |
25 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
26 | #include <linux/platform_data/ti-prm.h> |
27 | |
28 | #include "clockdomain.h" |
29 | #include "common.h" |
30 | #include "common-board-devices.h" |
31 | #include "control.h" |
32 | #include "omap_device.h" |
33 | #include "omap-secure.h" |
34 | #include "soc.h" |
35 | |
36 | static struct omap_hsmmc_platform_data __maybe_unused mmc_pdata[2]; |
37 | |
38 | struct pdata_init { |
39 | const char *compatible; |
40 | void (*fn)(void); |
41 | }; |
42 | |
43 | static struct of_dev_auxdata omap_auxdata_lookup[]; |
44 | |
45 | #ifdef CONFIG_MACH_NOKIA_N8X0 |
46 | static void __init omap2420_n8x0_legacy_init(void) |
47 | { |
48 | omap_auxdata_lookup[0].platform_data = n8x0_legacy_init(); |
49 | } |
50 | #else |
51 | #define omap2420_n8x0_legacy_init NULL |
52 | #endif |
53 | |
54 | #ifdef CONFIG_ARCH_OMAP3 |
55 | /* |
56 | * Configures GPIOs 126, 127 and 129 to 1.8V mode instead of 3.0V |
57 | * mode for MMC1 in case bootloader did not configure things. |
58 | * Note that if the pins are used for MMC1, pbias-regulator |
59 | * manages the IO voltage. |
60 | */ |
61 | static void __init omap3_gpio126_127_129(void) |
62 | { |
63 | u32 reg; |
64 | |
65 | reg = omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE); |
66 | reg &= ~OMAP343X_PBIASLITEVMODE1; |
67 | reg |= OMAP343X_PBIASLITEPWRDNZ1; |
68 | omap_ctrl_writel(reg, OMAP343X_CONTROL_PBIAS_LITE); |
69 | if (cpu_is_omap3630()) { |
70 | reg = omap_ctrl_readl(OMAP34XX_CONTROL_WKUP_CTRL); |
71 | reg |= OMAP36XX_GPIO_IO_PWRDNZ; |
72 | omap_ctrl_writel(reg, OMAP34XX_CONTROL_WKUP_CTRL); |
73 | } |
74 | } |
75 | |
76 | static void __init hsmmc2_internal_input_clk(void) |
77 | { |
78 | u32 reg; |
79 | |
80 | reg = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1); |
81 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; |
82 | omap_ctrl_writel(reg, OMAP343X_CONTROL_DEVCONF1); |
83 | } |
84 | |
85 | #ifdef CONFIG_OMAP_HWMOD |
86 | static struct iommu_platform_data omap3_iommu_pdata = { |
87 | .reset_name = "mmu" , |
88 | .assert_reset = omap_device_assert_hardreset, |
89 | .deassert_reset = omap_device_deassert_hardreset, |
90 | .device_enable = omap_device_enable, |
91 | .device_idle = omap_device_idle, |
92 | }; |
93 | |
94 | static struct iommu_platform_data omap3_iommu_isp_pdata = { |
95 | .device_enable = omap_device_enable, |
96 | .device_idle = omap_device_idle, |
97 | }; |
98 | #endif |
99 | |
100 | static void __init omap3_sbc_t3x_usb_hub_init(char *hub_name, int idx) |
101 | { |
102 | struct gpio_desc *d; |
103 | |
104 | /* This asserts the RESET line (reverse polarity) */ |
105 | d = gpiod_get_index(NULL, "reset" , idx, GPIOD_OUT_HIGH); |
106 | if (IS_ERR(d)) { |
107 | pr_err("Unable to get T3x USB reset GPIO descriptor\n" ); |
108 | return; |
109 | } |
110 | gpiod_set_consumer_name(d, hub_name); |
111 | gpiod_export(d, 0); |
112 | udelay(10); |
113 | /* De-assert RESET */ |
114 | gpiod_set_value(d, 0); |
115 | msleep(1); |
116 | } |
117 | |
118 | static struct gpiod_lookup_table omap3_sbc_t3x_usb_gpio_table = { |
119 | .dev_id = NULL, |
120 | .table = { |
121 | GPIO_LOOKUP_IDX("gpio-160-175" , 7, "reset" , 0, |
122 | GPIO_ACTIVE_LOW), |
123 | { } |
124 | }, |
125 | }; |
126 | |
127 | static void __init omap3_sbc_t3730_legacy_init(void) |
128 | { |
129 | gpiod_add_lookup_table(&omap3_sbc_t3x_usb_gpio_table); |
130 | omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub" , 0); |
131 | } |
132 | |
133 | static void __init omap3_sbc_t3530_legacy_init(void) |
134 | { |
135 | gpiod_add_lookup_table(&omap3_sbc_t3x_usb_gpio_table); |
136 | omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub" , 0); |
137 | } |
138 | |
139 | static void __init omap3_evm_legacy_init(void) |
140 | { |
141 | hsmmc2_internal_input_clk(); |
142 | } |
143 | |
144 | static void am35xx_enable_emac_int(void) |
145 | { |
146 | u32 v; |
147 | |
148 | v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); |
149 | v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR | |
150 | AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR); |
151 | omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); |
152 | omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ |
153 | } |
154 | |
155 | static void am35xx_disable_emac_int(void) |
156 | { |
157 | u32 v; |
158 | |
159 | v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); |
160 | v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR); |
161 | omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR); |
162 | omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */ |
163 | } |
164 | |
165 | static struct emac_platform_data am35xx_emac_pdata = { |
166 | .interrupt_enable = am35xx_enable_emac_int, |
167 | .interrupt_disable = am35xx_disable_emac_int, |
168 | }; |
169 | |
170 | static void __init am35xx_emac_reset(void) |
171 | { |
172 | u32 v; |
173 | |
174 | v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); |
175 | v &= ~AM35XX_CPGMACSS_SW_RST; |
176 | omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET); |
177 | omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ |
178 | } |
179 | |
180 | static struct gpiod_lookup_table cm_t3517_wlan_gpio_table = { |
181 | .dev_id = NULL, |
182 | .table = { |
183 | GPIO_LOOKUP("gpio-48-53" , 8, "power" , |
184 | GPIO_ACTIVE_HIGH), |
185 | GPIO_LOOKUP("gpio-0-15" , 4, "noe" , |
186 | GPIO_ACTIVE_HIGH), |
187 | { } |
188 | }, |
189 | }; |
190 | |
191 | static void __init omap3_sbc_t3517_wifi_init(void) |
192 | { |
193 | struct gpio_desc *d; |
194 | |
195 | gpiod_add_lookup_table(&cm_t3517_wlan_gpio_table); |
196 | |
197 | /* This asserts the RESET line (reverse polarity) */ |
198 | d = gpiod_get(NULL, "power" , GPIOD_OUT_HIGH); |
199 | if (IS_ERR(d)) { |
200 | pr_err("Unable to get CM T3517 WLAN power GPIO descriptor\n" ); |
201 | } else { |
202 | gpiod_set_consumer_name(d, "wlan pwr" ); |
203 | gpiod_export(d, 0); |
204 | } |
205 | |
206 | d = gpiod_get(NULL, "noe" , GPIOD_OUT_HIGH); |
207 | if (IS_ERR(d)) { |
208 | pr_err("Unable to get CM T3517 WLAN XCVR NOE GPIO descriptor\n" ); |
209 | } else { |
210 | gpiod_set_consumer_name(d, "xcvr noe" ); |
211 | gpiod_export(d, 0); |
212 | } |
213 | msleep(100); |
214 | gpiod_set_value(d, 0); |
215 | } |
216 | |
217 | static struct gpiod_lookup_table omap3_sbc_t3517_usb_gpio_table = { |
218 | .dev_id = NULL, |
219 | .table = { |
220 | GPIO_LOOKUP_IDX("gpio-144-159" , 8, "reset" , 0, |
221 | GPIO_ACTIVE_LOW), |
222 | GPIO_LOOKUP_IDX("gpio-96-111" , 2, "reset" , 1, |
223 | GPIO_ACTIVE_LOW), |
224 | { } |
225 | }, |
226 | }; |
227 | |
228 | static void __init omap3_sbc_t3517_legacy_init(void) |
229 | { |
230 | gpiod_add_lookup_table(&omap3_sbc_t3517_usb_gpio_table); |
231 | omap3_sbc_t3x_usb_hub_init("cm-t3517 usb hub" , 0); |
232 | omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub" , 1); |
233 | am35xx_emac_reset(); |
234 | hsmmc2_internal_input_clk(); |
235 | omap3_sbc_t3517_wifi_init(); |
236 | } |
237 | |
238 | static void __init am3517_evm_legacy_init(void) |
239 | { |
240 | am35xx_emac_reset(); |
241 | } |
242 | |
243 | static void __init nokia_n900_legacy_init(void) |
244 | { |
245 | hsmmc2_internal_input_clk(); |
246 | mmc_pdata[0].name = "external" ; |
247 | mmc_pdata[1].name = "internal" ; |
248 | |
249 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { |
250 | if (IS_ENABLED(CONFIG_ARM_ERRATA_430973)) { |
251 | pr_info("RX-51: Enabling ARM errata 430973 workaround\n" ); |
252 | /* set IBE to 1 */ |
253 | rx51_secure_update_aux_cr(BIT(6), 0); |
254 | } else { |
255 | pr_warn("RX-51: Not enabling ARM errata 430973 workaround\n" ); |
256 | pr_warn("Thumb binaries may crash randomly without this workaround\n" ); |
257 | } |
258 | } |
259 | } |
260 | |
261 | static void __init omap3_tao3530_legacy_init(void) |
262 | { |
263 | hsmmc2_internal_input_clk(); |
264 | } |
265 | |
266 | static void __init omap3_logicpd_torpedo_init(void) |
267 | { |
268 | omap3_gpio126_127_129(); |
269 | } |
270 | |
271 | /* omap3pandora legacy devices */ |
272 | |
273 | static struct platform_device pandora_backlight = { |
274 | .name = "pandora-backlight" , |
275 | .id = -1, |
276 | }; |
277 | |
278 | static struct gpiod_lookup_table pandora_soc_audio_gpios = { |
279 | .dev_id = "soc-audio" , |
280 | .table = { |
281 | GPIO_LOOKUP("gpio-112-127" , 6, "dac" , GPIO_ACTIVE_HIGH), |
282 | GPIO_LOOKUP("gpio-0-15" , 14, "amp" , GPIO_ACTIVE_HIGH), |
283 | { } |
284 | }, |
285 | }; |
286 | |
287 | static void __init omap3_pandora_legacy_init(void) |
288 | { |
289 | platform_device_register(&pandora_backlight); |
290 | gpiod_add_lookup_table(&pandora_soc_audio_gpios); |
291 | } |
292 | #endif /* CONFIG_ARCH_OMAP3 */ |
293 | |
294 | #ifdef CONFIG_SOC_DRA7XX |
295 | static struct iommu_platform_data dra7_ipu1_dsp_iommu_pdata = { |
296 | .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint, |
297 | }; |
298 | #endif |
299 | |
300 | static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk) |
301 | { |
302 | struct clk_hw *hw = __clk_get_hw(clk); |
303 | struct clockdomain *clkdm = NULL; |
304 | struct clk_hw_omap *hwclk; |
305 | |
306 | hwclk = to_clk_hw_omap(hw); |
307 | if (!omap2_clk_is_hw_omap(hw)) |
308 | return NULL; |
309 | |
310 | if (hwclk && hwclk->clkdm_name) |
311 | clkdm = clkdm_lookup(name: hwclk->clkdm_name); |
312 | |
313 | return clkdm; |
314 | } |
315 | |
316 | /** |
317 | * ti_sysc_clkdm_init - find clockdomain based on clock |
318 | * @fck: device functional clock |
319 | * @ick: device interface clock |
320 | * @dev: struct device |
321 | * |
322 | * Populate clockdomain based on clock. It is needed for |
323 | * clkdm_deny_idle() and clkdm_allow_idle() for blocking clockdomain |
324 | * clockdomain idle during reset, enable and idle. |
325 | * |
326 | * Note that we assume interconnect driver manages the clocks |
327 | * and do not need to populate oh->_clk for dynamically |
328 | * allocated modules. |
329 | */ |
330 | static int ti_sysc_clkdm_init(struct device *dev, |
331 | struct clk *fck, struct clk *ick, |
332 | struct ti_sysc_cookie *cookie) |
333 | { |
334 | if (!IS_ERR(ptr: fck)) |
335 | cookie->clkdm = ti_sysc_find_one_clockdomain(clk: fck); |
336 | if (cookie->clkdm) |
337 | return 0; |
338 | if (!IS_ERR(ptr: ick)) |
339 | cookie->clkdm = ti_sysc_find_one_clockdomain(clk: ick); |
340 | if (cookie->clkdm) |
341 | return 0; |
342 | |
343 | return -ENODEV; |
344 | } |
345 | |
346 | static void ti_sysc_clkdm_deny_idle(struct device *dev, |
347 | const struct ti_sysc_cookie *cookie) |
348 | { |
349 | if (cookie->clkdm) |
350 | clkdm_deny_idle(clkdm: cookie->clkdm); |
351 | } |
352 | |
353 | static void ti_sysc_clkdm_allow_idle(struct device *dev, |
354 | const struct ti_sysc_cookie *cookie) |
355 | { |
356 | if (cookie->clkdm) |
357 | clkdm_allow_idle(clkdm: cookie->clkdm); |
358 | } |
359 | |
360 | #ifdef CONFIG_OMAP_HWMOD |
361 | static int ti_sysc_enable_module(struct device *dev, |
362 | const struct ti_sysc_cookie *cookie) |
363 | { |
364 | if (!cookie->data) |
365 | return -EINVAL; |
366 | |
367 | return omap_hwmod_enable(cookie->data); |
368 | } |
369 | |
370 | static int ti_sysc_idle_module(struct device *dev, |
371 | const struct ti_sysc_cookie *cookie) |
372 | { |
373 | if (!cookie->data) |
374 | return -EINVAL; |
375 | |
376 | return omap_hwmod_idle(cookie->data); |
377 | } |
378 | |
379 | static int ti_sysc_shutdown_module(struct device *dev, |
380 | const struct ti_sysc_cookie *cookie) |
381 | { |
382 | if (!cookie->data) |
383 | return -EINVAL; |
384 | |
385 | return omap_hwmod_shutdown(cookie->data); |
386 | } |
387 | #endif /* CONFIG_OMAP_HWMOD */ |
388 | |
389 | static bool ti_sysc_soc_type_gp(void) |
390 | { |
391 | return omap_type() == OMAP2_DEVICE_TYPE_GP; |
392 | } |
393 | |
394 | static struct of_dev_auxdata omap_auxdata_lookup[]; |
395 | |
396 | static struct ti_sysc_platform_data ti_sysc_pdata = { |
397 | .auxdata = omap_auxdata_lookup, |
398 | .soc_type_gp = ti_sysc_soc_type_gp, |
399 | .init_clockdomain = ti_sysc_clkdm_init, |
400 | .clkdm_deny_idle = ti_sysc_clkdm_deny_idle, |
401 | .clkdm_allow_idle = ti_sysc_clkdm_allow_idle, |
402 | #ifdef CONFIG_OMAP_HWMOD |
403 | .init_module = omap_hwmod_init_module, |
404 | .enable_module = ti_sysc_enable_module, |
405 | .idle_module = ti_sysc_idle_module, |
406 | .shutdown_module = ti_sysc_shutdown_module, |
407 | #endif |
408 | }; |
409 | |
410 | static struct pcs_pdata pcs_pdata; |
411 | |
412 | void omap_pcs_legacy_init(int irq, void (*rearm)(void)) |
413 | { |
414 | pcs_pdata.irq = irq; |
415 | pcs_pdata.rearm = rearm; |
416 | } |
417 | |
418 | static struct ti_prm_platform_data ti_prm_pdata = { |
419 | .clkdm_deny_idle = clkdm_deny_idle, |
420 | .clkdm_allow_idle = clkdm_allow_idle, |
421 | .clkdm_lookup = clkdm_lookup, |
422 | }; |
423 | |
424 | #if defined(CONFIG_ARCH_OMAP3) && IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) |
425 | static struct omap_mcbsp_platform_data mcbsp_pdata; |
426 | static void __init omap3_mcbsp_init(void) |
427 | { |
428 | omap3_mcbsp_init_pdata_callback(&mcbsp_pdata); |
429 | } |
430 | #else |
431 | static void __init omap3_mcbsp_init(void) {} |
432 | #endif |
433 | |
434 | /* |
435 | * Few boards still need auxdata populated before we populate |
436 | * the dev entries in of_platform_populate(). |
437 | */ |
438 | static struct pdata_init auxdata_quirks[] __initdata = { |
439 | #ifdef CONFIG_SOC_OMAP2420 |
440 | { "nokia,n800" , omap2420_n8x0_legacy_init, }, |
441 | { "nokia,n810" , omap2420_n8x0_legacy_init, }, |
442 | { "nokia,n810-wimax" , omap2420_n8x0_legacy_init, }, |
443 | #endif |
444 | { /* sentinel */ }, |
445 | }; |
446 | |
447 | struct omap_sr_data __maybe_unused omap_sr_pdata[OMAP_SR_NR]; |
448 | |
449 | static struct of_dev_auxdata omap_auxdata_lookup[] = { |
450 | #ifdef CONFIG_MACH_NOKIA_N8X0 |
451 | OF_DEV_AUXDATA("ti,omap2420-mmc" , 0x4809c000, "mmci-omap.0" , NULL), |
452 | OF_DEV_AUXDATA("menelaus" , 0x72, "1-0072" , &n8x0_menelaus_platform_data), |
453 | #endif |
454 | #ifdef CONFIG_ARCH_OMAP3 |
455 | OF_DEV_AUXDATA("ti,omap2-iommu" , 0x5d000000, "5d000000.mmu" , |
456 | &omap3_iommu_pdata), |
457 | OF_DEV_AUXDATA("ti,omap2-iommu" , 0x480bd400, "480bd400.mmu" , |
458 | &omap3_iommu_isp_pdata), |
459 | OF_DEV_AUXDATA("ti,omap3-smartreflex-core" , 0x480cb000, |
460 | "480cb000.smartreflex" , &omap_sr_pdata[OMAP_SR_CORE]), |
461 | OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva" , 0x480c9000, |
462 | "480c9000.smartreflex" , &omap_sr_pdata[OMAP_SR_MPU]), |
463 | OF_DEV_AUXDATA("ti,omap3-hsmmc" , 0x4809c000, "4809c000.mmc" , &mmc_pdata[0]), |
464 | OF_DEV_AUXDATA("ti,omap3-hsmmc" , 0x480b4000, "480b4000.mmc" , &mmc_pdata[1]), |
465 | /* Only on am3517 */ |
466 | OF_DEV_AUXDATA("ti,davinci_mdio" , 0x5c030000, "davinci_mdio.0" , NULL), |
467 | OF_DEV_AUXDATA("ti,am3517-emac" , 0x5c000000, "davinci_emac.0" , |
468 | &am35xx_emac_pdata), |
469 | OF_DEV_AUXDATA("nokia,n900-rom-rng" , 0, NULL, rx51_secure_rng_call), |
470 | /* McBSP modules with sidetone core */ |
471 | #if IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) |
472 | OF_DEV_AUXDATA("ti,omap3-mcbsp" , 0x49022000, "49022000.mcbsp" , &mcbsp_pdata), |
473 | OF_DEV_AUXDATA("ti,omap3-mcbsp" , 0x49024000, "49024000.mcbsp" , &mcbsp_pdata), |
474 | #endif |
475 | #endif |
476 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) |
477 | OF_DEV_AUXDATA("ti,omap4-smartreflex-iva" , 0x4a0db000, |
478 | "4a0db000.smartreflex" , &omap_sr_pdata[OMAP_SR_IVA]), |
479 | OF_DEV_AUXDATA("ti,omap4-smartreflex-core" , 0x4a0dd000, |
480 | "4a0dd000.smartreflex" , &omap_sr_pdata[OMAP_SR_CORE]), |
481 | OF_DEV_AUXDATA("ti,omap4-smartreflex-mpu" , 0x4a0d9000, |
482 | "4a0d9000.smartreflex" , &omap_sr_pdata[OMAP_SR_MPU]), |
483 | #endif |
484 | #ifdef CONFIG_SOC_DRA7XX |
485 | OF_DEV_AUXDATA("ti,dra7-dsp-iommu" , 0x40d01000, "40d01000.mmu" , |
486 | &dra7_ipu1_dsp_iommu_pdata), |
487 | OF_DEV_AUXDATA("ti,dra7-dsp-iommu" , 0x41501000, "41501000.mmu" , |
488 | &dra7_ipu1_dsp_iommu_pdata), |
489 | OF_DEV_AUXDATA("ti,dra7-iommu" , 0x58882000, "58882000.mmu" , |
490 | &dra7_ipu1_dsp_iommu_pdata), |
491 | #endif |
492 | /* Common auxdata */ |
493 | OF_DEV_AUXDATA("simple-pm-bus" , 0, NULL, omap_auxdata_lookup), |
494 | OF_DEV_AUXDATA("ti,sysc" , 0, NULL, &ti_sysc_pdata), |
495 | OF_DEV_AUXDATA("pinctrl-single" , 0, NULL, &pcs_pdata), |
496 | OF_DEV_AUXDATA("ti,omap-prm-inst" , 0, NULL, &ti_prm_pdata), |
497 | OF_DEV_AUXDATA("ti,omap-sdma" , 0, NULL, &dma_plat_info), |
498 | { /* sentinel */ }, |
499 | }; |
500 | |
501 | /* |
502 | * Few boards still need to initialize some legacy devices with |
503 | * platform data until the drivers support device tree. |
504 | */ |
505 | static struct pdata_init pdata_quirks[] __initdata = { |
506 | #ifdef CONFIG_ARCH_OMAP3 |
507 | { "compulab,omap3-sbc-t3517" , omap3_sbc_t3517_legacy_init, }, |
508 | { "compulab,omap3-sbc-t3530" , omap3_sbc_t3530_legacy_init, }, |
509 | { "compulab,omap3-sbc-t3730" , omap3_sbc_t3730_legacy_init, }, |
510 | { "nokia,omap3-n900" , nokia_n900_legacy_init, }, |
511 | { "nokia,omap3-n9" , hsmmc2_internal_input_clk, }, |
512 | { "nokia,omap3-n950" , hsmmc2_internal_input_clk, }, |
513 | { "logicpd,dm3730-torpedo-devkit" , omap3_logicpd_torpedo_init, }, |
514 | { "ti,omap3-evm-37xx" , omap3_evm_legacy_init, }, |
515 | { "ti,am3517-evm" , am3517_evm_legacy_init, }, |
516 | { "technexion,omap3-tao3530" , omap3_tao3530_legacy_init, }, |
517 | { "openpandora,omap3-pandora-600mhz" , omap3_pandora_legacy_init, }, |
518 | { "openpandora,omap3-pandora-1ghz" , omap3_pandora_legacy_init, }, |
519 | #endif |
520 | { /* sentinel */ }, |
521 | }; |
522 | |
523 | static void pdata_quirks_check(struct pdata_init *quirks) |
524 | { |
525 | while (quirks->compatible) { |
526 | if (of_machine_is_compatible(compat: quirks->compatible)) { |
527 | if (quirks->fn) |
528 | quirks->fn(); |
529 | } |
530 | quirks++; |
531 | } |
532 | } |
533 | |
534 | static const char * const pdata_quirks_init_nodes[] = { |
535 | "prcm" , |
536 | "prm" , |
537 | }; |
538 | |
539 | static void __init |
540 | pdata_quirks_init_clocks(const struct of_device_id *omap_dt_match_table) |
541 | { |
542 | struct device_node *np; |
543 | int i; |
544 | |
545 | for (i = 0; i < ARRAY_SIZE(pdata_quirks_init_nodes); i++) { |
546 | np = of_find_node_by_name(NULL, name: pdata_quirks_init_nodes[i]); |
547 | if (!np) |
548 | continue; |
549 | |
550 | of_platform_populate(root: np, matches: omap_dt_match_table, |
551 | lookup: omap_auxdata_lookup, NULL); |
552 | |
553 | of_node_put(node: np); |
554 | } |
555 | } |
556 | |
557 | void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table) |
558 | { |
559 | /* |
560 | * We still need this for omap2420 and omap3 PM to work, others are |
561 | * using drivers/misc/sram.c already. |
562 | */ |
563 | if (of_machine_is_compatible(compat: "ti,omap2420" ) || |
564 | of_machine_is_compatible(compat: "ti,omap3" )) |
565 | omap_sdrc_init(NULL, NULL); |
566 | |
567 | if (of_machine_is_compatible(compat: "ti,omap3" )) |
568 | omap3_mcbsp_init(); |
569 | pdata_quirks_check(quirks: auxdata_quirks); |
570 | |
571 | pdata_quirks_init_clocks(omap_dt_match_table); |
572 | |
573 | of_platform_populate(NULL, matches: omap_dt_match_table, |
574 | lookup: omap_auxdata_lookup, NULL); |
575 | pdata_quirks_check(quirks: pdata_quirks); |
576 | } |
577 | |