Commit | Line | Data |
---|---|---|
bc3a59c1 DA |
1 | /* |
2 | * Copyright 2012 Freescale Semiconductor, Inc. | |
3 | * Copyright 2012 Linaro Ltd. | |
4 | * | |
5 | * The code contained herein is licensed under the GNU General Public | |
6 | * License. You may obtain a copy of the GNU General Public License | |
7 | * Version 2 or later at the following locations: | |
8 | * | |
9 | * http://www.opensource.org/licenses/gpl-license.html | |
10 | * http://www.gnu.org/copyleft/gpl.html | |
11 | */ | |
12 | ||
13 | #include <linux/clk.h> | |
3cb7825b | 14 | #include <linux/clk/mxs.h> |
bc3a59c1 | 15 | #include <linux/clkdev.h> |
2c7c2c1d | 16 | #include <linux/delay.h> |
bc3a59c1 | 17 | #include <linux/err.h> |
2c7c2c1d | 18 | #include <linux/gpio.h> |
bc3a59c1 | 19 | #include <linux/init.h> |
6a8e95b0 | 20 | #include <linux/irqchip/mxs.h> |
7b6d864b | 21 | #include <linux/reboot.h> |
3143bbb4 | 22 | #include <linux/micrel_phy.h> |
974a9af5 | 23 | #include <linux/of_address.h> |
bc3a59c1 | 24 | #include <linux/of_platform.h> |
3143bbb4 | 25 | #include <linux/phy.h> |
2c7c2c1d | 26 | #include <linux/pinctrl/consumer.h> |
2046338d | 27 | #include <linux/sys_soc.h> |
bc3a59c1 | 28 | #include <asm/mach/arch.h> |
1f629564 | 29 | #include <asm/mach/map.h> |
bc3a59c1 | 30 | #include <asm/mach/time.h> |
974a9af5 | 31 | #include <asm/system_misc.h> |
0b48d3a6 | 32 | |
45680995 SG |
33 | #include "pm.h" |
34 | ||
0b48d3a6 SG |
35 | /* MXS DIGCTL SAIF CLKMUX */ |
36 | #define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0 | |
37 | #define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1 | |
38 | #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2 | |
39 | #define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3 | |
40 | ||
2046338d FE |
41 | #define HW_DIGCTL_CHIPID 0x310 |
42 | #define HW_DIGCTL_CHIPID_MASK (0xffff << 16) | |
43 | #define HW_DIGCTL_REV_MASK 0xff | |
44 | #define HW_DIGCTL_CHIPID_MX23 (0x3780 << 16) | |
45 | #define HW_DIGCTL_CHIPID_MX28 (0x2800 << 16) | |
46 | ||
47 | #define MXS_CHIP_REVISION_1_0 0x10 | |
48 | #define MXS_CHIP_REVISION_1_1 0x11 | |
49 | #define MXS_CHIP_REVISION_1_2 0x12 | |
50 | #define MXS_CHIP_REVISION_1_3 0x13 | |
51 | #define MXS_CHIP_REVISION_1_4 0x14 | |
52 | #define MXS_CHIP_REV_UNKNOWN 0xff | |
53 | ||
0b48d3a6 SG |
54 | #define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr)) |
55 | ||
56 | #define MXS_SET_ADDR 0x4 | |
57 | #define MXS_CLR_ADDR 0x8 | |
58 | #define MXS_TOG_ADDR 0xc | |
59 | ||
2046338d FE |
60 | static u32 chipid; |
61 | static u32 socid; | |
62 | ||
56b7eec0 LW |
63 | static void __iomem *reset_addr; |
64 | ||
0b48d3a6 SG |
65 | static inline void __mxs_setl(u32 mask, void __iomem *reg) |
66 | { | |
67 | __raw_writel(mask, reg + MXS_SET_ADDR); | |
68 | } | |
69 | ||
70 | static inline void __mxs_clrl(u32 mask, void __iomem *reg) | |
71 | { | |
72 | __raw_writel(mask, reg + MXS_CLR_ADDR); | |
73 | } | |
74 | ||
75 | static inline void __mxs_togl(u32 mask, void __iomem *reg) | |
76 | { | |
77 | __raw_writel(mask, reg + MXS_TOG_ADDR); | |
78 | } | |
bc3a59c1 | 79 | |
1bff2d76 SG |
80 | #define OCOTP_WORD_OFFSET 0x20 |
81 | #define OCOTP_WORD_COUNT 0x20 | |
82 | ||
83 | #define BM_OCOTP_CTRL_BUSY (1 << 8) | |
84 | #define BM_OCOTP_CTRL_ERROR (1 << 9) | |
85 | #define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12) | |
86 | ||
87 | static DEFINE_MUTEX(ocotp_mutex); | |
88 | static u32 ocotp_words[OCOTP_WORD_COUNT]; | |
89 | ||
90 | static const u32 *mxs_get_ocotp(void) | |
91 | { | |
92 | struct device_node *np; | |
93 | void __iomem *ocotp_base; | |
94 | int timeout = 0x400; | |
95 | size_t i; | |
96 | static int once; | |
97 | ||
98 | if (once) | |
99 | return ocotp_words; | |
100 | ||
101 | np = of_find_compatible_node(NULL, NULL, "fsl,ocotp"); | |
102 | ocotp_base = of_iomap(np, 0); | |
103 | WARN_ON(!ocotp_base); | |
104 | ||
105 | mutex_lock(&ocotp_mutex); | |
106 | ||
107 | /* | |
108 | * clk_enable(hbus_clk) for ocotp can be skipped | |
109 | * as it must be on when system is running. | |
110 | */ | |
111 | ||
112 | /* try to clear ERROR bit */ | |
113 | __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base); | |
114 | ||
115 | /* check both BUSY and ERROR cleared */ | |
116 | while ((__raw_readl(ocotp_base) & | |
117 | (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout) | |
118 | cpu_relax(); | |
119 | ||
120 | if (unlikely(!timeout)) | |
121 | goto error_unlock; | |
122 | ||
123 | /* open OCOTP banks for read */ | |
124 | __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base); | |
125 | ||
126 | /* approximately wait 32 hclk cycles */ | |
127 | udelay(1); | |
128 | ||
129 | /* poll BUSY bit becoming cleared */ | |
130 | timeout = 0x400; | |
131 | while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout) | |
132 | cpu_relax(); | |
133 | ||
134 | if (unlikely(!timeout)) | |
135 | goto error_unlock; | |
136 | ||
137 | for (i = 0; i < OCOTP_WORD_COUNT; i++) | |
138 | ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET + | |
139 | i * 0x10); | |
140 | ||
141 | /* close banks for power saving */ | |
142 | __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base); | |
143 | ||
144 | once = 1; | |
145 | ||
146 | mutex_unlock(&ocotp_mutex); | |
147 | ||
148 | return ocotp_words; | |
149 | ||
150 | error_unlock: | |
151 | mutex_unlock(&ocotp_mutex); | |
152 | pr_err("%s: timeout in reading OCOTP\n", __func__); | |
153 | return NULL; | |
154 | } | |
155 | ||
5653acc2 SG |
156 | enum mac_oui { |
157 | OUI_FSL, | |
158 | OUI_DENX, | |
8eec4b31 | 159 | OUI_CRYSTALFONTZ, |
5653acc2 SG |
160 | }; |
161 | ||
162 | static void __init update_fec_mac_prop(enum mac_oui oui) | |
163 | { | |
164 | struct device_node *np, *from = NULL; | |
fa7c865a | 165 | struct property *newmac; |
5653acc2 SG |
166 | const u32 *ocotp = mxs_get_ocotp(); |
167 | u8 *macaddr; | |
168 | u32 val; | |
169 | int i; | |
170 | ||
171 | for (i = 0; i < 2; i++) { | |
172 | np = of_find_compatible_node(from, NULL, "fsl,imx28-fec"); | |
173 | if (!np) | |
174 | return; | |
16d47701 | 175 | |
5653acc2 SG |
176 | from = np; |
177 | ||
16d47701 MV |
178 | if (of_get_property(np, "local-mac-address", NULL)) |
179 | continue; | |
180 | ||
5653acc2 SG |
181 | newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL); |
182 | if (!newmac) | |
183 | return; | |
184 | newmac->value = newmac + 1; | |
185 | newmac->length = 6; | |
186 | ||
187 | newmac->name = kstrdup("local-mac-address", GFP_KERNEL); | |
188 | if (!newmac->name) { | |
189 | kfree(newmac); | |
190 | return; | |
191 | } | |
192 | ||
193 | /* | |
194 | * OCOTP only stores the last 4 octets for each mac address, | |
195 | * so hard-code OUI here. | |
196 | */ | |
197 | macaddr = newmac->value; | |
198 | switch (oui) { | |
199 | case OUI_FSL: | |
200 | macaddr[0] = 0x00; | |
201 | macaddr[1] = 0x04; | |
202 | macaddr[2] = 0x9f; | |
203 | break; | |
204 | case OUI_DENX: | |
205 | macaddr[0] = 0xc0; | |
206 | macaddr[1] = 0xe5; | |
207 | macaddr[2] = 0x4e; | |
208 | break; | |
8eec4b31 MR |
209 | case OUI_CRYSTALFONTZ: |
210 | macaddr[0] = 0x58; | |
211 | macaddr[1] = 0xb9; | |
212 | macaddr[2] = 0xe1; | |
213 | break; | |
5653acc2 SG |
214 | } |
215 | val = ocotp[i]; | |
216 | macaddr[3] = (val >> 16) & 0xff; | |
217 | macaddr[4] = (val >> 8) & 0xff; | |
218 | macaddr[5] = (val >> 0) & 0xff; | |
219 | ||
79d1c712 | 220 | of_update_property(np, newmac); |
5653acc2 SG |
221 | } |
222 | } | |
223 | ||
8fa62e11 | 224 | static inline void enable_clk_enet_out(void) |
bc3a59c1 | 225 | { |
8fa62e11 | 226 | struct clk *clk = clk_get_sys("enet_out", NULL); |
bc3a59c1 | 227 | |
bc3a59c1 DA |
228 | if (!IS_ERR(clk)) |
229 | clk_prepare_enable(clk); | |
8fa62e11 | 230 | } |
5653acc2 | 231 | |
8fa62e11 MV |
232 | static void __init imx28_evk_init(void) |
233 | { | |
5653acc2 | 234 | update_fec_mac_prop(OUI_FSL); |
ab2815c3 | 235 | |
e317317a | 236 | mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); |
bc3a59c1 DA |
237 | } |
238 | ||
3143bbb4 SG |
239 | static int apx4devkit_phy_fixup(struct phy_device *phy) |
240 | { | |
241 | phy->dev_flags |= MICREL_PHY_50MHZ_CLK; | |
242 | return 0; | |
243 | } | |
244 | ||
245 | static void __init apx4devkit_init(void) | |
246 | { | |
247 | enable_clk_enet_out(); | |
248 | ||
249 | if (IS_BUILTIN(CONFIG_PHYLIB)) | |
510d573f | 250 | phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK, |
3143bbb4 SG |
251 | apx4devkit_phy_fixup); |
252 | } | |
253 | ||
2c7c2c1d SG |
254 | #define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0) |
255 | #define ENET0_MDIO__GPIO_4_1 MXS_GPIO_NR(4, 1) | |
256 | #define ENET0_RX_EN__GPIO_4_2 MXS_GPIO_NR(4, 2) | |
257 | #define ENET0_RXD0__GPIO_4_3 MXS_GPIO_NR(4, 3) | |
258 | #define ENET0_RXD1__GPIO_4_4 MXS_GPIO_NR(4, 4) | |
259 | #define ENET0_TX_EN__GPIO_4_6 MXS_GPIO_NR(4, 6) | |
260 | #define ENET0_TXD0__GPIO_4_7 MXS_GPIO_NR(4, 7) | |
261 | #define ENET0_TXD1__GPIO_4_8 MXS_GPIO_NR(4, 8) | |
262 | #define ENET_CLK__GPIO_4_16 MXS_GPIO_NR(4, 16) | |
263 | ||
264 | #define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29) | |
265 | #define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13) | |
266 | #define TX28_FEC_nINT MXS_GPIO_NR(4, 5) | |
267 | ||
268 | static const struct gpio tx28_gpios[] __initconst = { | |
269 | { ENET0_MDC__GPIO_4_0, GPIOF_OUT_INIT_LOW, "GPIO_4_0" }, | |
270 | { ENET0_MDIO__GPIO_4_1, GPIOF_OUT_INIT_LOW, "GPIO_4_1" }, | |
271 | { ENET0_RX_EN__GPIO_4_2, GPIOF_OUT_INIT_LOW, "GPIO_4_2" }, | |
272 | { ENET0_RXD0__GPIO_4_3, GPIOF_OUT_INIT_LOW, "GPIO_4_3" }, | |
273 | { ENET0_RXD1__GPIO_4_4, GPIOF_OUT_INIT_LOW, "GPIO_4_4" }, | |
274 | { ENET0_TX_EN__GPIO_4_6, GPIOF_OUT_INIT_LOW, "GPIO_4_6" }, | |
275 | { ENET0_TXD0__GPIO_4_7, GPIOF_OUT_INIT_LOW, "GPIO_4_7" }, | |
276 | { ENET0_TXD1__GPIO_4_8, GPIOF_OUT_INIT_LOW, "GPIO_4_8" }, | |
277 | { ENET_CLK__GPIO_4_16, GPIOF_OUT_INIT_LOW, "GPIO_4_16" }, | |
278 | { TX28_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" }, | |
279 | { TX28_FEC_PHY_RESET, GPIOF_OUT_INIT_LOW, "fec-phy-reset" }, | |
280 | { TX28_FEC_nINT, GPIOF_DIR_IN, "fec-int" }, | |
281 | }; | |
282 | ||
283 | static void __init tx28_post_init(void) | |
284 | { | |
285 | struct device_node *np; | |
286 | struct platform_device *pdev; | |
287 | struct pinctrl *pctl; | |
288 | int ret; | |
289 | ||
290 | enable_clk_enet_out(); | |
291 | ||
292 | np = of_find_compatible_node(NULL, NULL, "fsl,imx28-fec"); | |
293 | pdev = of_find_device_by_node(np); | |
294 | if (!pdev) { | |
295 | pr_err("%s: failed to find fec device\n", __func__); | |
296 | return; | |
297 | } | |
298 | ||
299 | pctl = pinctrl_get_select(&pdev->dev, "gpio_mode"); | |
300 | if (IS_ERR(pctl)) { | |
301 | pr_err("%s: failed to get pinctrl state\n", __func__); | |
302 | return; | |
303 | } | |
304 | ||
305 | ret = gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios)); | |
306 | if (ret) { | |
307 | pr_err("%s: failed to request gpios: %d\n", __func__, ret); | |
308 | return; | |
309 | } | |
310 | ||
311 | /* Power up fec phy */ | |
312 | gpio_set_value(TX28_FEC_PHY_POWER, 1); | |
313 | msleep(26); /* 25ms according to data sheet */ | |
314 | ||
315 | /* Mode strap pins */ | |
316 | gpio_set_value(ENET0_RX_EN__GPIO_4_2, 1); | |
317 | gpio_set_value(ENET0_RXD0__GPIO_4_3, 1); | |
318 | gpio_set_value(ENET0_RXD1__GPIO_4_4, 1); | |
319 | ||
320 | udelay(100); /* minimum assertion time for nRST */ | |
321 | ||
322 | /* Deasserting FEC PHY RESET */ | |
323 | gpio_set_value(TX28_FEC_PHY_RESET, 1); | |
324 | ||
325 | pinctrl_put(pctl); | |
326 | } | |
327 | ||
ed138c36 | 328 | static void __init crystalfontz_init(void) |
8eec4b31 | 329 | { |
8eec4b31 MR |
330 | update_fec_mac_prop(OUI_CRYSTALFONTZ); |
331 | } | |
332 | ||
e0ec2f39 MV |
333 | static void __init m28cu3_init(void) |
334 | { | |
335 | update_fec_mac_prop(OUI_DENX); | |
336 | } | |
337 | ||
2046338d | 338 | static const char __init *mxs_get_soc_id(void) |
e0f7d905 | 339 | { |
2046338d FE |
340 | struct device_node *np; |
341 | void __iomem *digctl_base; | |
342 | ||
343 | np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl"); | |
344 | digctl_base = of_iomap(np, 0); | |
345 | WARN_ON(!digctl_base); | |
346 | ||
347 | chipid = readl(digctl_base + HW_DIGCTL_CHIPID); | |
348 | socid = chipid & HW_DIGCTL_CHIPID_MASK; | |
349 | ||
350 | iounmap(digctl_base); | |
351 | of_node_put(np); | |
352 | ||
353 | switch (socid) { | |
354 | case HW_DIGCTL_CHIPID_MX23: | |
355 | return "i.MX23"; | |
356 | case HW_DIGCTL_CHIPID_MX28: | |
357 | return "i.MX28"; | |
358 | default: | |
359 | return "Unknown"; | |
360 | } | |
361 | } | |
362 | ||
363 | static u32 __init mxs_get_cpu_rev(void) | |
364 | { | |
365 | u32 rev = chipid & HW_DIGCTL_REV_MASK; | |
366 | ||
367 | switch (socid) { | |
368 | case HW_DIGCTL_CHIPID_MX23: | |
369 | switch (rev) { | |
370 | case 0x0: | |
371 | return MXS_CHIP_REVISION_1_0; | |
372 | case 0x1: | |
373 | return MXS_CHIP_REVISION_1_1; | |
374 | case 0x2: | |
375 | return MXS_CHIP_REVISION_1_2; | |
376 | case 0x3: | |
377 | return MXS_CHIP_REVISION_1_3; | |
378 | case 0x4: | |
379 | return MXS_CHIP_REVISION_1_4; | |
380 | default: | |
381 | return MXS_CHIP_REV_UNKNOWN; | |
382 | } | |
383 | case HW_DIGCTL_CHIPID_MX28: | |
384 | switch (rev) { | |
385 | case 0x0: | |
386 | return MXS_CHIP_REVISION_1_1; | |
387 | case 0x1: | |
388 | return MXS_CHIP_REVISION_1_2; | |
389 | default: | |
390 | return MXS_CHIP_REV_UNKNOWN; | |
391 | } | |
392 | default: | |
393 | return MXS_CHIP_REV_UNKNOWN; | |
394 | } | |
395 | } | |
396 | ||
397 | static const char __init *mxs_get_revision(void) | |
398 | { | |
399 | u32 rev = mxs_get_cpu_rev(); | |
400 | ||
401 | if (rev != MXS_CHIP_REV_UNKNOWN) | |
e115d63c | 402 | return kasprintf(GFP_KERNEL, "%d.%d", (rev >> 4) & 0xf, |
2046338d FE |
403 | rev & 0xf); |
404 | else | |
405 | return kasprintf(GFP_KERNEL, "%s", "Unknown"); | |
e0f7d905 MR |
406 | } |
407 | ||
56b7eec0 LW |
408 | #define MX23_CLKCTRL_RESET_OFFSET 0x120 |
409 | #define MX28_CLKCTRL_RESET_OFFSET 0x1e0 | |
410 | ||
411 | static int __init mxs_restart_init(void) | |
412 | { | |
413 | struct device_node *np; | |
414 | ||
415 | np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl"); | |
416 | reset_addr = of_iomap(np, 0); | |
417 | if (!reset_addr) | |
418 | return -ENODEV; | |
419 | ||
420 | if (of_device_is_compatible(np, "fsl,imx23-clkctrl")) | |
421 | reset_addr += MX23_CLKCTRL_RESET_OFFSET; | |
422 | else | |
423 | reset_addr += MX28_CLKCTRL_RESET_OFFSET; | |
424 | of_node_put(np); | |
425 | ||
426 | return 0; | |
427 | } | |
428 | ||
bc3a59c1 DA |
429 | static void __init mxs_machine_init(void) |
430 | { | |
2046338d FE |
431 | struct device_node *root; |
432 | struct device *parent; | |
433 | struct soc_device *soc_dev; | |
434 | struct soc_device_attribute *soc_dev_attr; | |
435 | int ret; | |
436 | ||
437 | soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); | |
438 | if (!soc_dev_attr) | |
439 | return; | |
440 | ||
441 | root = of_find_node_by_path("/"); | |
442 | ret = of_property_read_string(root, "model", &soc_dev_attr->machine); | |
443 | if (ret) | |
444 | return; | |
445 | ||
446 | soc_dev_attr->family = "Freescale MXS Family"; | |
447 | soc_dev_attr->soc_id = mxs_get_soc_id(); | |
448 | soc_dev_attr->revision = mxs_get_revision(); | |
449 | ||
450 | soc_dev = soc_device_register(soc_dev_attr); | |
451 | if (IS_ERR(soc_dev)) { | |
452 | kfree(soc_dev_attr->revision); | |
453 | kfree(soc_dev_attr); | |
454 | return; | |
455 | } | |
456 | ||
457 | parent = soc_device_to_device(soc_dev); | |
458 | ||
bc3a59c1 DA |
459 | if (of_machine_is_compatible("fsl,imx28-evk")) |
460 | imx28_evk_init(); | |
3143bbb4 SG |
461 | else if (of_machine_is_compatible("bluegiga,apx4devkit")) |
462 | apx4devkit_init(); | |
f71f2e95 | 463 | else if (of_machine_is_compatible("crystalfontz,cfa10036")) |
ed138c36 | 464 | crystalfontz_init(); |
e0ec2f39 MV |
465 | else if (of_machine_is_compatible("msr,m28cu3")) |
466 | m28cu3_init(); | |
bc3a59c1 DA |
467 | |
468 | of_platform_populate(NULL, of_default_bus_match_table, | |
496322bc | 469 | NULL, parent); |
2c7c2c1d | 470 | |
56b7eec0 LW |
471 | mxs_restart_init(); |
472 | ||
2c7c2c1d SG |
473 | if (of_machine_is_compatible("karo,tx28")) |
474 | tx28_post_init(); | |
bc3a59c1 DA |
475 | } |
476 | ||
974a9af5 SG |
477 | #define MXS_CLKCTRL_RESET_CHIP (1 << 1) |
478 | ||
479 | /* | |
480 | * Reset the system. It is called by machine_restart(). | |
481 | */ | |
7b6d864b | 482 | static void mxs_restart(enum reboot_mode mode, const char *cmd) |
974a9af5 | 483 | { |
56b7eec0 LW |
484 | if (reset_addr) { |
485 | /* reset the chip */ | |
486 | __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr); | |
974a9af5 | 487 | |
56b7eec0 | 488 | pr_err("Failed to assert the chip reset\n"); |
974a9af5 | 489 | |
56b7eec0 LW |
490 | /* Delay to allow the serial port to show the message */ |
491 | mdelay(50); | |
492 | } | |
974a9af5 | 493 | |
974a9af5 SG |
494 | /* We'll take a jump through zero as a poor second */ |
495 | soft_restart(0); | |
496 | } | |
497 | ||
39490ab0 | 498 | static const char *mxs_dt_compat[] __initdata = { |
bc3a59c1 | 499 | "fsl,imx28", |
39490ab0 | 500 | "fsl,imx23", |
bc3a59c1 DA |
501 | NULL, |
502 | }; | |
503 | ||
39490ab0 | 504 | DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)") |
4e0a1b8c | 505 | .handle_irq = icoll_handle_irq, |
bc3a59c1 | 506 | .init_machine = mxs_machine_init, |
45680995 | 507 | .init_late = mxs_pm_init, |
39490ab0 | 508 | .dt_compat = mxs_dt_compat, |
bc3a59c1 DA |
509 | .restart = mxs_restart, |
510 | MACHINE_END |