blob: 7d759f1c26b19fe61a5df4813861b18b3071d509 [file] [log] [blame]
Kumar Galaeed32002006-01-13 11:19:13 -06001/*
2 * FSL SoC setup code
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
Vitaly Bordugfba43662006-09-21 17:26:34 +04006 * 2006 (c) MontaVista Software, Inc.
7 * Vitaly Bordug <vbordug@ru.mvista.com>
8 *
Kumar Galaeed32002006-01-13 11:19:13 -06009 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
Kumar Galaeed32002006-01-13 11:19:13 -060015#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/major.h>
20#include <linux/delay.h>
21#include <linux/irq.h>
22#include <linux/module.h>
23#include <linux/device.h>
24#include <linux/platform_device.h>
25#include <linux/fsl_devices.h>
Vitaly Bordugfba43662006-09-21 17:26:34 +040026#include <linux/fs_enet_pd.h>
27#include <linux/fs_uart_pd.h>
Kumar Galaeed32002006-01-13 11:19:13 -060028
29#include <asm/system.h>
30#include <asm/atomic.h>
31#include <asm/io.h>
32#include <asm/irq.h>
Vitaly Bordugfba43662006-09-21 17:26:34 +040033#include <asm/time.h>
Kumar Galaeed32002006-01-13 11:19:13 -060034#include <asm/prom.h>
35#include <sysdev/fsl_soc.h>
36#include <mm/mmu_decl.h>
Vitaly Bordugfba43662006-09-21 17:26:34 +040037#include <asm/cpm2.h>
Kumar Galaeed32002006-01-13 11:19:13 -060038
Vitaly Bordugd3465c92006-09-21 22:38:05 +040039extern void init_fcc_ioports(struct fs_platform_info*);
Vitaly Borduged943c12006-10-02 22:41:50 +040040extern void init_scc_ioports(struct fs_uart_platform_info*);
Kumar Galaeed32002006-01-13 11:19:13 -060041static phys_addr_t immrbase = -1;
42
43phys_addr_t get_immrbase(void)
44{
45 struct device_node *soc;
46
47 if (immrbase != -1)
48 return immrbase;
49
50 soc = of_find_node_by_type(NULL, "soc");
Kumar Gala2fb07d72006-01-23 16:58:04 -060051 if (soc) {
Kumar Galaeed32002006-01-13 11:19:13 -060052 unsigned int size;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +100053 const void *prop = get_property(soc, "reg", &size);
Vitaly Bordugfba43662006-09-21 17:26:34 +040054
55 if (prop)
56 immrbase = of_translate_address(soc, prop);
Kumar Galaeed32002006-01-13 11:19:13 -060057 of_node_put(soc);
58 };
59
60 return immrbase;
61}
Kumar Gala2fb07d72006-01-23 16:58:04 -060062
Kumar Galaeed32002006-01-13 11:19:13 -060063EXPORT_SYMBOL(get_immrbase);
64
Vitaly Bordugfba43662006-09-21 17:26:34 +040065#ifdef CONFIG_CPM2
66
67static u32 brgfreq = -1;
68
69u32 get_brgfreq(void)
70{
71 struct device_node *node;
72
73 if (brgfreq != -1)
74 return brgfreq;
75
76 node = of_find_node_by_type(NULL, "cpm");
77 if (node) {
78 unsigned int size;
79 const unsigned int *prop = get_property(node, "brg-frequency",
80 &size);
81
82 if (prop)
83 brgfreq = *prop;
84 of_node_put(node);
85 };
86
87 return brgfreq;
88}
89
90EXPORT_SYMBOL(get_brgfreq);
91
92static u32 fs_baudrate = -1;
93
94u32 get_baudrate(void)
95{
96 struct device_node *node;
97
98 if (fs_baudrate != -1)
99 return fs_baudrate;
100
101 node = of_find_node_by_type(NULL, "serial");
102 if (node) {
103 unsigned int size;
104 const unsigned int *prop = get_property(node, "current-speed",
105 &size);
106
107 if (prop)
108 fs_baudrate = *prop;
109 of_node_put(node);
110 };
111
112 return fs_baudrate;
113}
114
115EXPORT_SYMBOL(get_baudrate);
116#endif /* CONFIG_CPM2 */
117
Kumar Gala2fb07d72006-01-23 16:58:04 -0600118static int __init gfar_mdio_of_init(void)
Kumar Galaeed32002006-01-13 11:19:13 -0600119{
120 struct device_node *np;
121 unsigned int i;
Kumar Gala2fb07d72006-01-23 16:58:04 -0600122 struct platform_device *mdio_dev;
Kumar Galaeed32002006-01-13 11:19:13 -0600123 struct resource res;
124 int ret;
125
Kumar Gala2fb07d72006-01-23 16:58:04 -0600126 for (np = NULL, i = 0;
127 (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
128 i++) {
Kumar Galaeed32002006-01-13 11:19:13 -0600129 int k;
130 struct device_node *child = NULL;
131 struct gianfar_mdio_data mdio_data;
132
133 memset(&res, 0, sizeof(res));
134 memset(&mdio_data, 0, sizeof(mdio_data));
135
136 ret = of_address_to_resource(np, 0, &res);
137 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600138 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600139
Kumar Gala2fb07d72006-01-23 16:58:04 -0600140 mdio_dev =
141 platform_device_register_simple("fsl-gianfar_mdio",
142 res.start, &res, 1);
Kumar Galaeed32002006-01-13 11:19:13 -0600143 if (IS_ERR(mdio_dev)) {
144 ret = PTR_ERR(mdio_dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600145 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600146 }
147
148 for (k = 0; k < 32; k++)
149 mdio_data.irq[k] = -1;
150
151 while ((child = of_get_next_child(np, child)) != NULL) {
Vitaly Bordugfba43662006-09-21 17:26:34 +0400152 int irq = irq_of_parse_and_map(child, 0);
153 if (irq != NO_IRQ) {
154 const u32 *id = get_property(child, "reg", NULL);
155 mdio_data.irq[*id] = irq;
156 }
Kumar Galaeed32002006-01-13 11:19:13 -0600157 }
158
Kumar Gala2fb07d72006-01-23 16:58:04 -0600159 ret =
160 platform_device_add_data(mdio_dev, &mdio_data,
161 sizeof(struct gianfar_mdio_data));
Kumar Galaeed32002006-01-13 11:19:13 -0600162 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600163 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600164 }
165
Kumar Gala2fb07d72006-01-23 16:58:04 -0600166 return 0;
167
168unreg:
169 platform_device_unregister(mdio_dev);
170err:
171 return ret;
172}
173
174arch_initcall(gfar_mdio_of_init);
175
176static const char *gfar_tx_intr = "tx";
177static const char *gfar_rx_intr = "rx";
178static const char *gfar_err_intr = "error";
179
180static int __init gfar_of_init(void)
181{
182 struct device_node *np;
183 unsigned int i;
184 struct platform_device *gfar_dev;
185 struct resource res;
186 int ret;
187
188 for (np = NULL, i = 0;
189 (np = of_find_compatible_node(np, "network", "gianfar")) != NULL;
190 i++) {
Kumar Galaeed32002006-01-13 11:19:13 -0600191 struct resource r[4];
192 struct device_node *phy, *mdio;
193 struct gianfar_platform_data gfar_data;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000194 const unsigned int *id;
195 const char *model;
196 const void *mac_addr;
197 const phandle *ph;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400198 int n_res = 2;
Kumar Galaeed32002006-01-13 11:19:13 -0600199
200 memset(r, 0, sizeof(r));
201 memset(&gfar_data, 0, sizeof(gfar_data));
202
203 ret = of_address_to_resource(np, 0, &r[0]);
204 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600205 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600206
Jon Loeliger919fede2006-07-31 15:35:41 -0500207 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
Kumar Galaeed32002006-01-13 11:19:13 -0600208 r[1].flags = IORESOURCE_IRQ;
209
210 model = get_property(np, "model", NULL);
211
212 /* If we aren't the FEC we have multiple interrupts */
213 if (model && strcasecmp(model, "FEC")) {
214 r[1].name = gfar_tx_intr;
215
216 r[2].name = gfar_rx_intr;
Jon Loeliger919fede2006-07-31 15:35:41 -0500217 r[2].start = r[2].end = irq_of_parse_and_map(np, 1);
Kumar Galaeed32002006-01-13 11:19:13 -0600218 r[2].flags = IORESOURCE_IRQ;
219
220 r[3].name = gfar_err_intr;
Jon Loeliger919fede2006-07-31 15:35:41 -0500221 r[3].start = r[3].end = irq_of_parse_and_map(np, 2);
Kumar Galaeed32002006-01-13 11:19:13 -0600222 r[3].flags = IORESOURCE_IRQ;
Jon Loeliger919fede2006-07-31 15:35:41 -0500223
224 n_res += 2;
Kumar Galaeed32002006-01-13 11:19:13 -0600225 }
226
Kumar Gala2fb07d72006-01-23 16:58:04 -0600227 gfar_dev =
228 platform_device_register_simple("fsl-gianfar", i, &r[0],
Vitaly Bordugfba43662006-09-21 17:26:34 +0400229 n_res);
Kumar Galaeed32002006-01-13 11:19:13 -0600230
231 if (IS_ERR(gfar_dev)) {
232 ret = PTR_ERR(gfar_dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600233 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600234 }
235
Jon Loeligerf5831652006-08-17 08:42:35 -0500236 mac_addr = get_property(np, "local-mac-address", NULL);
237 if (mac_addr == NULL)
238 mac_addr = get_property(np, "mac-address", NULL);
239 if (mac_addr == NULL) {
240 /* Obsolete */
241 mac_addr = get_property(np, "address", NULL);
242 }
243
244 if (mac_addr)
245 memcpy(gfar_data.mac_addr, mac_addr, 6);
Kumar Galaeed32002006-01-13 11:19:13 -0600246
247 if (model && !strcasecmp(model, "TSEC"))
248 gfar_data.device_flags =
Kumar Gala2fb07d72006-01-23 16:58:04 -0600249 FSL_GIANFAR_DEV_HAS_GIGABIT |
250 FSL_GIANFAR_DEV_HAS_COALESCE |
251 FSL_GIANFAR_DEV_HAS_RMON |
252 FSL_GIANFAR_DEV_HAS_MULTI_INTR;
Kumar Galaeed32002006-01-13 11:19:13 -0600253 if (model && !strcasecmp(model, "eTSEC"))
254 gfar_data.device_flags =
Kumar Gala2fb07d72006-01-23 16:58:04 -0600255 FSL_GIANFAR_DEV_HAS_GIGABIT |
256 FSL_GIANFAR_DEV_HAS_COALESCE |
257 FSL_GIANFAR_DEV_HAS_RMON |
258 FSL_GIANFAR_DEV_HAS_MULTI_INTR |
259 FSL_GIANFAR_DEV_HAS_CSUM |
260 FSL_GIANFAR_DEV_HAS_VLAN |
261 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
Kumar Galaeed32002006-01-13 11:19:13 -0600262
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000263 ph = get_property(np, "phy-handle", NULL);
Kumar Galaeed32002006-01-13 11:19:13 -0600264 phy = of_find_node_by_phandle(*ph);
265
266 if (phy == NULL) {
267 ret = -ENODEV;
Kumar Gala2fb07d72006-01-23 16:58:04 -0600268 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600269 }
270
271 mdio = of_get_parent(phy);
272
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000273 id = get_property(phy, "reg", NULL);
Kumar Galaeed32002006-01-13 11:19:13 -0600274 ret = of_address_to_resource(mdio, 0, &res);
275 if (ret) {
276 of_node_put(phy);
277 of_node_put(mdio);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600278 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600279 }
280
281 gfar_data.phy_id = *id;
282 gfar_data.bus_id = res.start;
283
284 of_node_put(phy);
285 of_node_put(mdio);
286
Kumar Gala2fb07d72006-01-23 16:58:04 -0600287 ret =
288 platform_device_add_data(gfar_dev, &gfar_data,
289 sizeof(struct
290 gianfar_platform_data));
Kumar Galaeed32002006-01-13 11:19:13 -0600291 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600292 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600293 }
294
295 return 0;
296
Kumar Gala2fb07d72006-01-23 16:58:04 -0600297unreg:
Kumar Galaeed32002006-01-13 11:19:13 -0600298 platform_device_unregister(gfar_dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600299err:
Kumar Galaeed32002006-01-13 11:19:13 -0600300 return ret;
301}
Kumar Gala2fb07d72006-01-23 16:58:04 -0600302
Kumar Galaeed32002006-01-13 11:19:13 -0600303arch_initcall(gfar_of_init);
304
305static int __init fsl_i2c_of_init(void)
306{
307 struct device_node *np;
308 unsigned int i;
309 struct platform_device *i2c_dev;
310 int ret;
311
Kumar Gala2fb07d72006-01-23 16:58:04 -0600312 for (np = NULL, i = 0;
313 (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
314 i++) {
Kumar Galaeed32002006-01-13 11:19:13 -0600315 struct resource r[2];
316 struct fsl_i2c_platform_data i2c_data;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000317 const unsigned char *flags = NULL;
Kumar Galaeed32002006-01-13 11:19:13 -0600318
319 memset(&r, 0, sizeof(r));
320 memset(&i2c_data, 0, sizeof(i2c_data));
321
322 ret = of_address_to_resource(np, 0, &r[0]);
323 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600324 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600325
Jon Loeliger919fede2006-07-31 15:35:41 -0500326 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
Kumar Galaeed32002006-01-13 11:19:13 -0600327 r[1].flags = IORESOURCE_IRQ;
328
329 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
330 if (IS_ERR(i2c_dev)) {
331 ret = PTR_ERR(i2c_dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600332 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600333 }
334
335 i2c_data.device_flags = 0;
336 flags = get_property(np, "dfsrr", NULL);
337 if (flags)
338 i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
339
340 flags = get_property(np, "fsl5200-clocking", NULL);
341 if (flags)
342 i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
343
Kumar Gala2fb07d72006-01-23 16:58:04 -0600344 ret =
345 platform_device_add_data(i2c_dev, &i2c_data,
346 sizeof(struct
347 fsl_i2c_platform_data));
Kumar Galaeed32002006-01-13 11:19:13 -0600348 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600349 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600350 }
351
352 return 0;
353
Kumar Gala2fb07d72006-01-23 16:58:04 -0600354unreg:
Kumar Galaeed32002006-01-13 11:19:13 -0600355 platform_device_unregister(i2c_dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600356err:
Kumar Galaeed32002006-01-13 11:19:13 -0600357 return ret;
358}
Kumar Gala2fb07d72006-01-23 16:58:04 -0600359
Kumar Galaeed32002006-01-13 11:19:13 -0600360arch_initcall(fsl_i2c_of_init);
361
362#ifdef CONFIG_PPC_83xx
363static int __init mpc83xx_wdt_init(void)
364{
365 struct resource r;
366 struct device_node *soc, *np;
367 struct platform_device *dev;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000368 const unsigned int *freq;
Kumar Galaeed32002006-01-13 11:19:13 -0600369 int ret;
370
371 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
372
373 if (!np) {
374 ret = -ENODEV;
Kumar Gala2fb07d72006-01-23 16:58:04 -0600375 goto nodev;
Kumar Galaeed32002006-01-13 11:19:13 -0600376 }
377
378 soc = of_find_node_by_type(NULL, "soc");
379
380 if (!soc) {
381 ret = -ENODEV;
Kumar Gala2fb07d72006-01-23 16:58:04 -0600382 goto nosoc;
Kumar Galaeed32002006-01-13 11:19:13 -0600383 }
384
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000385 freq = get_property(soc, "bus-frequency", NULL);
Kumar Galaeed32002006-01-13 11:19:13 -0600386 if (!freq) {
387 ret = -ENODEV;
Kumar Gala2fb07d72006-01-23 16:58:04 -0600388 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600389 }
390
391 memset(&r, 0, sizeof(r));
392
393 ret = of_address_to_resource(np, 0, &r);
394 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600395 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600396
397 dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
398 if (IS_ERR(dev)) {
399 ret = PTR_ERR(dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600400 goto err;
Kumar Galaeed32002006-01-13 11:19:13 -0600401 }
402
403 ret = platform_device_add_data(dev, freq, sizeof(int));
404 if (ret)
Kumar Gala2fb07d72006-01-23 16:58:04 -0600405 goto unreg;
Kumar Galaeed32002006-01-13 11:19:13 -0600406
407 of_node_put(soc);
408 of_node_put(np);
409
410 return 0;
411
Kumar Gala2fb07d72006-01-23 16:58:04 -0600412unreg:
Kumar Galaeed32002006-01-13 11:19:13 -0600413 platform_device_unregister(dev);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600414err:
Kumar Galaeed32002006-01-13 11:19:13 -0600415 of_node_put(soc);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600416nosoc:
Kumar Galaeed32002006-01-13 11:19:13 -0600417 of_node_put(np);
Kumar Gala2fb07d72006-01-23 16:58:04 -0600418nodev:
Kumar Galaeed32002006-01-13 11:19:13 -0600419 return ret;
420}
Kumar Gala2fb07d72006-01-23 16:58:04 -0600421
Kumar Galaeed32002006-01-13 11:19:13 -0600422arch_initcall(mpc83xx_wdt_init);
423#endif
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600424
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000425static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600426{
427 if (!phy_type)
428 return FSL_USB2_PHY_NONE;
429 if (!strcasecmp(phy_type, "ulpi"))
430 return FSL_USB2_PHY_ULPI;
431 if (!strcasecmp(phy_type, "utmi"))
432 return FSL_USB2_PHY_UTMI;
433 if (!strcasecmp(phy_type, "utmi_wide"))
434 return FSL_USB2_PHY_UTMI_WIDE;
435 if (!strcasecmp(phy_type, "serial"))
436 return FSL_USB2_PHY_SERIAL;
437
438 return FSL_USB2_PHY_NONE;
439}
440
441static int __init fsl_usb_of_init(void)
442{
443 struct device_node *np;
444 unsigned int i;
Kumar Gala01cced22006-04-11 10:07:16 -0500445 struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600446 int ret;
447
448 for (np = NULL, i = 0;
449 (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
450 i++) {
451 struct resource r[2];
452 struct fsl_usb2_platform_data usb_data;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000453 const unsigned char *prop = NULL;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600454
455 memset(&r, 0, sizeof(r));
456 memset(&usb_data, 0, sizeof(usb_data));
457
458 ret = of_address_to_resource(np, 0, &r[0]);
459 if (ret)
460 goto err;
461
Jon Loeliger919fede2006-07-31 15:35:41 -0500462 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600463 r[1].flags = IORESOURCE_IRQ;
464
Kumar Gala01cced22006-04-11 10:07:16 -0500465 usb_dev_mph =
466 platform_device_register_simple("fsl-ehci", i, r, 2);
467 if (IS_ERR(usb_dev_mph)) {
468 ret = PTR_ERR(usb_dev_mph);
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600469 goto err;
470 }
471
Kumar Gala01cced22006-04-11 10:07:16 -0500472 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
473 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600474
475 usb_data.operating_mode = FSL_USB2_MPH_HOST;
476
477 prop = get_property(np, "port0", NULL);
478 if (prop)
479 usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
480
481 prop = get_property(np, "port1", NULL);
482 if (prop)
483 usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
484
485 prop = get_property(np, "phy_type", NULL);
486 usb_data.phy_mode = determine_usb_phy(prop);
487
488 ret =
Kumar Gala01cced22006-04-11 10:07:16 -0500489 platform_device_add_data(usb_dev_mph, &usb_data,
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600490 sizeof(struct
491 fsl_usb2_platform_data));
492 if (ret)
Kumar Gala01cced22006-04-11 10:07:16 -0500493 goto unreg_mph;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600494 }
495
Kumar Gala01cced22006-04-11 10:07:16 -0500496 for (np = NULL;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600497 (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
498 i++) {
499 struct resource r[2];
500 struct fsl_usb2_platform_data usb_data;
Jeremy Kerra7f67bd2006-07-12 15:35:54 +1000501 const unsigned char *prop = NULL;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600502
503 memset(&r, 0, sizeof(r));
504 memset(&usb_data, 0, sizeof(usb_data));
505
506 ret = of_address_to_resource(np, 0, &r[0]);
507 if (ret)
Kumar Gala01cced22006-04-11 10:07:16 -0500508 goto unreg_mph;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600509
Jon Loeliger919fede2006-07-31 15:35:41 -0500510 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600511 r[1].flags = IORESOURCE_IRQ;
512
Kumar Gala01cced22006-04-11 10:07:16 -0500513 usb_dev_dr =
514 platform_device_register_simple("fsl-ehci", i, r, 2);
515 if (IS_ERR(usb_dev_dr)) {
516 ret = PTR_ERR(usb_dev_dr);
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600517 goto err;
518 }
519
Kumar Gala01cced22006-04-11 10:07:16 -0500520 usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL;
521 usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600522
523 usb_data.operating_mode = FSL_USB2_DR_HOST;
524
525 prop = get_property(np, "phy_type", NULL);
526 usb_data.phy_mode = determine_usb_phy(prop);
527
528 ret =
Kumar Gala01cced22006-04-11 10:07:16 -0500529 platform_device_add_data(usb_dev_dr, &usb_data,
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600530 sizeof(struct
531 fsl_usb2_platform_data));
532 if (ret)
Kumar Gala01cced22006-04-11 10:07:16 -0500533 goto unreg_dr;
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600534 }
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600535 return 0;
536
Kumar Gala01cced22006-04-11 10:07:16 -0500537unreg_dr:
538 if (usb_dev_dr)
539 platform_device_unregister(usb_dev_dr);
540unreg_mph:
541 if (usb_dev_mph)
542 platform_device_unregister(usb_dev_mph);
Kumar Gala4b10cfd2006-02-02 12:31:00 -0600543err:
544 return ret;
545}
546
Kumar Gala01cced22006-04-11 10:07:16 -0500547arch_initcall(fsl_usb_of_init);
Vitaly Bordugfba43662006-09-21 17:26:34 +0400548
549#ifdef CONFIG_CPM2
550
551static const char fcc_regs[] = "fcc_regs";
552static const char fcc_regs_c[] = "fcc_regs_c";
553static const char fcc_pram[] = "fcc_pram";
554static char bus_id[9][BUS_ID_SIZE];
555
556static int __init fs_enet_of_init(void)
557{
558 struct device_node *np;
559 unsigned int i;
560 struct platform_device *fs_enet_dev;
561 struct resource res;
562 int ret;
563
564 for (np = NULL, i = 0;
565 (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
566 i++) {
567 struct resource r[4];
568 struct device_node *phy, *mdio;
569 struct fs_platform_info fs_enet_data;
Vitaly Borduged943c12006-10-02 22:41:50 +0400570 const unsigned int *id, *phy_addr, phy_irq;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400571 const void *mac_addr;
572 const phandle *ph;
573 const char *model;
574
575 memset(r, 0, sizeof(r));
576 memset(&fs_enet_data, 0, sizeof(fs_enet_data));
577
578 ret = of_address_to_resource(np, 0, &r[0]);
579 if (ret)
580 goto err;
581 r[0].name = fcc_regs;
582
583 ret = of_address_to_resource(np, 1, &r[1]);
584 if (ret)
585 goto err;
586 r[1].name = fcc_pram;
587
588 ret = of_address_to_resource(np, 2, &r[2]);
589 if (ret)
590 goto err;
591 r[2].name = fcc_regs_c;
Vitaly Borduged943c12006-10-02 22:41:50 +0400592 fs_enet_data.fcc_regs_c = r[2].start;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400593
594 r[3].start = r[3].end = irq_of_parse_and_map(np, 0);
595 r[3].flags = IORESOURCE_IRQ;
596
597 fs_enet_dev =
598 platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
599
600 if (IS_ERR(fs_enet_dev)) {
601 ret = PTR_ERR(fs_enet_dev);
602 goto err;
603 }
604
605 model = get_property(np, "model", NULL);
606 if (model == NULL) {
607 ret = -ENODEV;
608 goto unreg;
609 }
610
611 mac_addr = get_property(np, "mac-address", NULL);
612 memcpy(fs_enet_data.macaddr, mac_addr, 6);
613
614 ph = get_property(np, "phy-handle", NULL);
615 phy = of_find_node_by_phandle(*ph);
616
617 if (phy == NULL) {
618 ret = -ENODEV;
619 goto unreg;
620 }
621
622 phy_addr = get_property(phy, "reg", NULL);
623 fs_enet_data.phy_addr = *phy_addr;
624
Vitaly Borduged943c12006-10-02 22:41:50 +0400625 phy_irq = get_property(phy, "interrupts", NULL);
626
Vitaly Bordugfba43662006-09-21 17:26:34 +0400627 id = get_property(np, "device-id", NULL);
628 fs_enet_data.fs_no = *id;
Vitaly Bordug611a15a2006-09-21 22:38:05 +0400629 strcpy(fs_enet_data.fs_type, model);
Vitaly Bordugfba43662006-09-21 17:26:34 +0400630
631 mdio = of_get_parent(phy);
632 ret = of_address_to_resource(mdio, 0, &res);
633 if (ret) {
634 of_node_put(phy);
635 of_node_put(mdio);
636 goto unreg;
637 }
638
Vitaly Bordugd3465c92006-09-21 22:38:05 +0400639 fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
640 fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
641
Vitaly Bordugfba43662006-09-21 17:26:34 +0400642 if (strstr(model, "FCC")) {
Vitaly Bordug611a15a2006-09-21 22:38:05 +0400643 int fcc_index = *id - 1;
Vitaly Borduged943c12006-10-02 22:41:50 +0400644 unsigned char* mdio_bb_prop;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400645
Vitaly Bordugfc8e50e2006-09-21 22:37:58 +0400646 fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
Vitaly Bordugfba43662006-09-21 17:26:34 +0400647 fs_enet_data.rx_ring = 32;
648 fs_enet_data.tx_ring = 32;
649 fs_enet_data.rx_copybreak = 240;
650 fs_enet_data.use_napi = 0;
651 fs_enet_data.napi_weight = 17;
652 fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
653 fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
654 fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index);
655
656 snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
657 (u32)res.start, fs_enet_data.phy_addr);
658 fs_enet_data.bus_id = (char*)&bus_id[(*id)];
Vitaly Bordugd3465c92006-09-21 22:38:05 +0400659 fs_enet_data.init_ioports = init_fcc_ioports;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400660
Vitaly Borduged943c12006-10-02 22:41:50 +0400661 mdio_bb_prop = get_property(phy, "bitbang", NULL);
662 if (mdio_bb_prop) {
663 struct platform_device *fs_enet_mdio_bb_dev;
664 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400665
Vitaly Borduged943c12006-10-02 22:41:50 +0400666 fs_enet_mdio_bb_dev =
667 platform_device_register_simple("fsl-bb-mdio",
668 i, NULL, 0);
669 memset(&fs_enet_mdio_bb_data, 0,
670 sizeof(struct fs_mii_bb_platform_info));
671 fs_enet_mdio_bb_data.mdio_dat.bit =
672 mdio_bb_prop[0];
673 fs_enet_mdio_bb_data.mdio_dir.bit =
674 mdio_bb_prop[1];
675 fs_enet_mdio_bb_data.mdc_dat.bit =
676 mdio_bb_prop[2];
677 fs_enet_mdio_bb_data.mdio_port =
678 mdio_bb_prop[3];
679 fs_enet_mdio_bb_data.mdc_port =
680 mdio_bb_prop[4];
681 fs_enet_mdio_bb_data.delay =
682 mdio_bb_prop[5];
683
684 fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
685 fs_enet_mdio_bb_data.irq[1] = -1;
686 fs_enet_mdio_bb_data.irq[2] = -1;
687 fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
688 fs_enet_mdio_bb_data.irq[31] = -1;
689
690 fs_enet_mdio_bb_data.mdio_dat.offset =
691 (u32)&cpm2_immr->im_ioport.iop_pdatc;
692 fs_enet_mdio_bb_data.mdio_dir.offset =
693 (u32)&cpm2_immr->im_ioport.iop_pdirc;
694 fs_enet_mdio_bb_data.mdc_dat.offset =
695 (u32)&cpm2_immr->im_ioport.iop_pdatc;
696
697 ret = platform_device_add_data(
698 fs_enet_mdio_bb_dev,
699 &fs_enet_mdio_bb_data,
700 sizeof(struct fs_mii_bb_platform_info));
701 if (ret)
702 goto unreg;
703 }
704
705 of_node_put(phy);
706 of_node_put(mdio);
707
708 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
709 sizeof(struct
710 fs_platform_info));
Vitaly Bordugfba43662006-09-21 17:26:34 +0400711 if (ret)
712 goto unreg;
713 }
714 return 0;
715
716unreg:
717 platform_device_unregister(fs_enet_dev);
718err:
719 return ret;
720}
721
722arch_initcall(fs_enet_of_init);
723
724static const char scc_regs[] = "regs";
725static const char scc_pram[] = "pram";
726
727static int __init cpm_uart_of_init(void)
728{
729 struct device_node *np;
730 unsigned int i;
731 struct platform_device *cpm_uart_dev;
732 int ret;
733
734 for (np = NULL, i = 0;
735 (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
736 i++) {
737 struct resource r[3];
738 struct fs_uart_platform_info cpm_uart_data;
739 const int *id;
Vitaly Bordug611a15a2006-09-21 22:38:05 +0400740 const char *model;
Vitaly Bordugfba43662006-09-21 17:26:34 +0400741
742 memset(r, 0, sizeof(r));
743 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
744
745 ret = of_address_to_resource(np, 0, &r[0]);
746 if (ret)
747 goto err;
748
749 r[0].name = scc_regs;
750
751 ret = of_address_to_resource(np, 1, &r[1]);
752 if (ret)
753 goto err;
754 r[1].name = scc_pram;
755
756 r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
757 r[2].flags = IORESOURCE_IRQ;
758
759 cpm_uart_dev =
760 platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
761
762 if (IS_ERR(cpm_uart_dev)) {
763 ret = PTR_ERR(cpm_uart_dev);
764 goto err;
765 }
766
767 id = get_property(np, "device-id", NULL);
768 cpm_uart_data.fs_no = *id;
Vitaly Bordug611a15a2006-09-21 22:38:05 +0400769
770 model = (char*)get_property(np, "model", NULL);
771 strcpy(cpm_uart_data.fs_type, model);
772
Vitaly Bordugfba43662006-09-21 17:26:34 +0400773 cpm_uart_data.uart_clk = ppc_proc_freq;
774
775 cpm_uart_data.tx_num_fifo = 4;
776 cpm_uart_data.tx_buf_size = 32;
777 cpm_uart_data.rx_num_fifo = 4;
778 cpm_uart_data.rx_buf_size = 32;
Vitaly Bordugd3465c92006-09-21 22:38:05 +0400779 cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
780 cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
Vitaly Bordugfba43662006-09-21 17:26:34 +0400781
782 ret =
783 platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
784 sizeof(struct
785 fs_uart_platform_info));
786 if (ret)
787 goto unreg;
788 }
789
790 return 0;
791
792unreg:
793 platform_device_unregister(cpm_uart_dev);
794err:
795 return ret;
796}
797
798arch_initcall(cpm_uart_of_init);
799#endif /* CONFIG_CPM2 */