[POWERPC] add of_get_mac_address and update fsl_soc.c to use it
[linux-2.6.git] / arch / powerpc / sysdev / fsl_soc.c
1 /*
2  * FSL SoC setup code
3  *
4  * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5  *
6  * 2006 (c) MontaVista Software, Inc.
7  * Vitaly Bordug <vbordug@ru.mvista.com>
8  *
9  * 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
15 #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/phy.h>
26 #include <linux/fsl_devices.h>
27 #include <linux/fs_enet_pd.h>
28 #include <linux/fs_uart_pd.h>
29
30 #include <asm/system.h>
31 #include <asm/atomic.h>
32 #include <asm/io.h>
33 #include <asm/irq.h>
34 #include <asm/time.h>
35 #include <asm/prom.h>
36 #include <sysdev/fsl_soc.h>
37 #include <mm/mmu_decl.h>
38 #include <asm/cpm2.h>
39
40 extern void init_fcc_ioports(struct fs_platform_info*);
41 extern void init_fec_ioports(struct fs_platform_info*);
42 extern void init_smc_ioports(struct fs_uart_platform_info*);
43 static phys_addr_t immrbase = -1;
44
45 phys_addr_t get_immrbase(void)
46 {
47         struct device_node *soc;
48
49         if (immrbase != -1)
50                 return immrbase;
51
52         soc = of_find_node_by_type(NULL, "soc");
53         if (soc) {
54                 unsigned int size;
55                 const void *prop = get_property(soc, "reg", &size);
56
57                 if (prop)
58                         immrbase = of_translate_address(soc, prop);
59                 of_node_put(soc);
60         };
61
62         return immrbase;
63 }
64
65 EXPORT_SYMBOL(get_immrbase);
66
67 #if defined(CONFIG_CPM2) || defined(CONFIG_8xx)
68
69 static u32 brgfreq = -1;
70
71 u32 get_brgfreq(void)
72 {
73         struct device_node *node;
74
75         if (brgfreq != -1)
76                 return brgfreq;
77
78         node = of_find_node_by_type(NULL, "cpm");
79         if (node) {
80                 unsigned int size;
81                 const unsigned int *prop = get_property(node, "brg-frequency",
82                                         &size);
83
84                 if (prop)
85                         brgfreq = *prop;
86                 of_node_put(node);
87         };
88
89         return brgfreq;
90 }
91
92 EXPORT_SYMBOL(get_brgfreq);
93
94 static u32 fs_baudrate = -1;
95
96 u32 get_baudrate(void)
97 {
98         struct device_node *node;
99
100         if (fs_baudrate != -1)
101                 return fs_baudrate;
102
103         node = of_find_node_by_type(NULL, "serial");
104         if (node) {
105                 unsigned int size;
106                 const unsigned int *prop = get_property(node, "current-speed",
107                                 &size);
108
109                 if (prop)
110                         fs_baudrate = *prop;
111                 of_node_put(node);
112         };
113
114         return fs_baudrate;
115 }
116
117 EXPORT_SYMBOL(get_baudrate);
118 #endif /* CONFIG_CPM2 */
119
120 static int __init gfar_mdio_of_init(void)
121 {
122         struct device_node *np;
123         unsigned int i;
124         struct platform_device *mdio_dev;
125         struct resource res;
126         int ret;
127
128         for (np = NULL, i = 0;
129              (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
130              i++) {
131                 int k;
132                 struct device_node *child = NULL;
133                 struct gianfar_mdio_data mdio_data;
134
135                 memset(&res, 0, sizeof(res));
136                 memset(&mdio_data, 0, sizeof(mdio_data));
137
138                 ret = of_address_to_resource(np, 0, &res);
139                 if (ret)
140                         goto err;
141
142                 mdio_dev =
143                     platform_device_register_simple("fsl-gianfar_mdio",
144                                                     res.start, &res, 1);
145                 if (IS_ERR(mdio_dev)) {
146                         ret = PTR_ERR(mdio_dev);
147                         goto err;
148                 }
149
150                 for (k = 0; k < 32; k++)
151                         mdio_data.irq[k] = PHY_POLL;
152
153                 while ((child = of_get_next_child(np, child)) != NULL) {
154                         int irq = irq_of_parse_and_map(child, 0);
155                         if (irq != NO_IRQ) {
156                                 const u32 *id = get_property(child, "reg", NULL);
157                                 mdio_data.irq[*id] = irq;
158                         }
159                 }
160
161                 ret =
162                     platform_device_add_data(mdio_dev, &mdio_data,
163                                              sizeof(struct gianfar_mdio_data));
164                 if (ret)
165                         goto unreg;
166         }
167
168         return 0;
169
170 unreg:
171         platform_device_unregister(mdio_dev);
172 err:
173         return ret;
174 }
175
176 arch_initcall(gfar_mdio_of_init);
177
178 static const char *gfar_tx_intr = "tx";
179 static const char *gfar_rx_intr = "rx";
180 static const char *gfar_err_intr = "error";
181
182
183 static int __init gfar_of_init(void)
184 {
185         struct device_node *np;
186         unsigned int i;
187         struct platform_device *gfar_dev;
188         struct resource res;
189         int ret;
190
191         for (np = NULL, i = 0;
192              (np = of_find_compatible_node(np, "network", "gianfar")) != NULL;
193              i++) {
194                 struct resource r[4];
195                 struct device_node *phy, *mdio;
196                 struct gianfar_platform_data gfar_data;
197                 const unsigned int *id;
198                 const char *model;
199                 const void *mac_addr;
200                 const phandle *ph;
201                 int n_res = 2;
202
203                 memset(r, 0, sizeof(r));
204                 memset(&gfar_data, 0, sizeof(gfar_data));
205
206                 ret = of_address_to_resource(np, 0, &r[0]);
207                 if (ret)
208                         goto err;
209
210                 of_irq_to_resource(np, 0, &r[1]);
211
212                 model = get_property(np, "model", NULL);
213
214                 /* If we aren't the FEC we have multiple interrupts */
215                 if (model && strcasecmp(model, "FEC")) {
216                         r[1].name = gfar_tx_intr;
217
218                         r[2].name = gfar_rx_intr;
219                         of_irq_to_resource(np, 1, &r[2]);
220
221                         r[3].name = gfar_err_intr;
222                         of_irq_to_resource(np, 2, &r[3]);
223
224                         n_res += 2;
225                 }
226
227                 gfar_dev =
228                     platform_device_register_simple("fsl-gianfar", i, &r[0],
229                                                     n_res);
230
231                 if (IS_ERR(gfar_dev)) {
232                         ret = PTR_ERR(gfar_dev);
233                         goto err;
234                 }
235
236                 mac_addr = of_get_mac_address(np);
237                 if (mac_addr)
238                         memcpy(gfar_data.mac_addr, mac_addr, 6);
239
240                 if (model && !strcasecmp(model, "TSEC"))
241                         gfar_data.device_flags =
242                             FSL_GIANFAR_DEV_HAS_GIGABIT |
243                             FSL_GIANFAR_DEV_HAS_COALESCE |
244                             FSL_GIANFAR_DEV_HAS_RMON |
245                             FSL_GIANFAR_DEV_HAS_MULTI_INTR;
246                 if (model && !strcasecmp(model, "eTSEC"))
247                         gfar_data.device_flags =
248                             FSL_GIANFAR_DEV_HAS_GIGABIT |
249                             FSL_GIANFAR_DEV_HAS_COALESCE |
250                             FSL_GIANFAR_DEV_HAS_RMON |
251                             FSL_GIANFAR_DEV_HAS_MULTI_INTR |
252                             FSL_GIANFAR_DEV_HAS_CSUM |
253                             FSL_GIANFAR_DEV_HAS_VLAN |
254                             FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
255
256                 ph = get_property(np, "phy-handle", NULL);
257                 phy = of_find_node_by_phandle(*ph);
258
259                 if (phy == NULL) {
260                         ret = -ENODEV;
261                         goto unreg;
262                 }
263
264                 mdio = of_get_parent(phy);
265
266                 id = get_property(phy, "reg", NULL);
267                 ret = of_address_to_resource(mdio, 0, &res);
268                 if (ret) {
269                         of_node_put(phy);
270                         of_node_put(mdio);
271                         goto unreg;
272                 }
273
274                 gfar_data.phy_id = *id;
275                 gfar_data.bus_id = res.start;
276
277                 of_node_put(phy);
278                 of_node_put(mdio);
279
280                 ret =
281                     platform_device_add_data(gfar_dev, &gfar_data,
282                                              sizeof(struct
283                                                     gianfar_platform_data));
284                 if (ret)
285                         goto unreg;
286         }
287
288         return 0;
289
290 unreg:
291         platform_device_unregister(gfar_dev);
292 err:
293         return ret;
294 }
295
296 arch_initcall(gfar_of_init);
297
298 static int __init fsl_i2c_of_init(void)
299 {
300         struct device_node *np;
301         unsigned int i;
302         struct platform_device *i2c_dev;
303         int ret;
304
305         for (np = NULL, i = 0;
306              (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
307              i++) {
308                 struct resource r[2];
309                 struct fsl_i2c_platform_data i2c_data;
310                 const unsigned char *flags = NULL;
311
312                 memset(&r, 0, sizeof(r));
313                 memset(&i2c_data, 0, sizeof(i2c_data));
314
315                 ret = of_address_to_resource(np, 0, &r[0]);
316                 if (ret)
317                         goto err;
318
319                 of_irq_to_resource(np, 0, &r[1]);
320
321                 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
322                 if (IS_ERR(i2c_dev)) {
323                         ret = PTR_ERR(i2c_dev);
324                         goto err;
325                 }
326
327                 i2c_data.device_flags = 0;
328                 flags = get_property(np, "dfsrr", NULL);
329                 if (flags)
330                         i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR;
331
332                 flags = get_property(np, "fsl5200-clocking", NULL);
333                 if (flags)
334                         i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
335
336                 ret =
337                     platform_device_add_data(i2c_dev, &i2c_data,
338                                              sizeof(struct
339                                                     fsl_i2c_platform_data));
340                 if (ret)
341                         goto unreg;
342         }
343
344         return 0;
345
346 unreg:
347         platform_device_unregister(i2c_dev);
348 err:
349         return ret;
350 }
351
352 arch_initcall(fsl_i2c_of_init);
353
354 #ifdef CONFIG_PPC_83xx
355 static int __init mpc83xx_wdt_init(void)
356 {
357         struct resource r;
358         struct device_node *soc, *np;
359         struct platform_device *dev;
360         const unsigned int *freq;
361         int ret;
362
363         np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
364
365         if (!np) {
366                 ret = -ENODEV;
367                 goto nodev;
368         }
369
370         soc = of_find_node_by_type(NULL, "soc");
371
372         if (!soc) {
373                 ret = -ENODEV;
374                 goto nosoc;
375         }
376
377         freq = get_property(soc, "bus-frequency", NULL);
378         if (!freq) {
379                 ret = -ENODEV;
380                 goto err;
381         }
382
383         memset(&r, 0, sizeof(r));
384
385         ret = of_address_to_resource(np, 0, &r);
386         if (ret)
387                 goto err;
388
389         dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
390         if (IS_ERR(dev)) {
391                 ret = PTR_ERR(dev);
392                 goto err;
393         }
394
395         ret = platform_device_add_data(dev, freq, sizeof(int));
396         if (ret)
397                 goto unreg;
398
399         of_node_put(soc);
400         of_node_put(np);
401
402         return 0;
403
404 unreg:
405         platform_device_unregister(dev);
406 err:
407         of_node_put(soc);
408 nosoc:
409         of_node_put(np);
410 nodev:
411         return ret;
412 }
413
414 arch_initcall(mpc83xx_wdt_init);
415 #endif
416
417 static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
418 {
419         if (!phy_type)
420                 return FSL_USB2_PHY_NONE;
421         if (!strcasecmp(phy_type, "ulpi"))
422                 return FSL_USB2_PHY_ULPI;
423         if (!strcasecmp(phy_type, "utmi"))
424                 return FSL_USB2_PHY_UTMI;
425         if (!strcasecmp(phy_type, "utmi_wide"))
426                 return FSL_USB2_PHY_UTMI_WIDE;
427         if (!strcasecmp(phy_type, "serial"))
428                 return FSL_USB2_PHY_SERIAL;
429
430         return FSL_USB2_PHY_NONE;
431 }
432
433 static int __init fsl_usb_of_init(void)
434 {
435         struct device_node *np;
436         unsigned int i;
437         struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
438                 *usb_dev_dr_client = NULL;
439         int ret;
440
441         for (np = NULL, i = 0;
442              (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
443              i++) {
444                 struct resource r[2];
445                 struct fsl_usb2_platform_data usb_data;
446                 const unsigned char *prop = NULL;
447
448                 memset(&r, 0, sizeof(r));
449                 memset(&usb_data, 0, sizeof(usb_data));
450
451                 ret = of_address_to_resource(np, 0, &r[0]);
452                 if (ret)
453                         goto err;
454
455                 of_irq_to_resource(np, 0, &r[1]);
456
457                 usb_dev_mph =
458                     platform_device_register_simple("fsl-ehci", i, r, 2);
459                 if (IS_ERR(usb_dev_mph)) {
460                         ret = PTR_ERR(usb_dev_mph);
461                         goto err;
462                 }
463
464                 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
465                 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
466
467                 usb_data.operating_mode = FSL_USB2_MPH_HOST;
468
469                 prop = get_property(np, "port0", NULL);
470                 if (prop)
471                         usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
472
473                 prop = get_property(np, "port1", NULL);
474                 if (prop)
475                         usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
476
477                 prop = get_property(np, "phy_type", NULL);
478                 usb_data.phy_mode = determine_usb_phy(prop);
479
480                 ret =
481                     platform_device_add_data(usb_dev_mph, &usb_data,
482                                              sizeof(struct
483                                                     fsl_usb2_platform_data));
484                 if (ret)
485                         goto unreg_mph;
486         }
487
488         for (np = NULL;
489              (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
490              i++) {
491                 struct resource r[2];
492                 struct fsl_usb2_platform_data usb_data;
493                 const unsigned char *prop = NULL;
494
495                 memset(&r, 0, sizeof(r));
496                 memset(&usb_data, 0, sizeof(usb_data));
497
498                 ret = of_address_to_resource(np, 0, &r[0]);
499                 if (ret)
500                         goto unreg_mph;
501
502                 of_irq_to_resource(np, 0, &r[1]);
503
504                 prop = get_property(np, "dr_mode", NULL);
505
506                 if (!prop || !strcmp(prop, "host")) {
507                         usb_data.operating_mode = FSL_USB2_DR_HOST;
508                         usb_dev_dr_host = platform_device_register_simple(
509                                         "fsl-ehci", i, r, 2);
510                         if (IS_ERR(usb_dev_dr_host)) {
511                                 ret = PTR_ERR(usb_dev_dr_host);
512                                 goto err;
513                         }
514                 } else if (prop && !strcmp(prop, "peripheral")) {
515                         usb_data.operating_mode = FSL_USB2_DR_DEVICE;
516                         usb_dev_dr_client = platform_device_register_simple(
517                                         "fsl-usb2-udc", i, r, 2);
518                         if (IS_ERR(usb_dev_dr_client)) {
519                                 ret = PTR_ERR(usb_dev_dr_client);
520                                 goto err;
521                         }
522                 } else if (prop && !strcmp(prop, "otg")) {
523                         usb_data.operating_mode = FSL_USB2_DR_OTG;
524                         usb_dev_dr_host = platform_device_register_simple(
525                                         "fsl-ehci", i, r, 2);
526                         if (IS_ERR(usb_dev_dr_host)) {
527                                 ret = PTR_ERR(usb_dev_dr_host);
528                                 goto err;
529                         }
530                         usb_dev_dr_client = platform_device_register_simple(
531                                         "fsl-usb2-udc", i, r, 2);
532                         if (IS_ERR(usb_dev_dr_client)) {
533                                 ret = PTR_ERR(usb_dev_dr_client);
534                                 goto err;
535                         }
536                 } else {
537                         ret = -EINVAL;
538                         goto err;
539                 }
540
541                 prop = get_property(np, "phy_type", NULL);
542                 usb_data.phy_mode = determine_usb_phy(prop);
543
544                 if (usb_dev_dr_host) {
545                         usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
546                         usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
547                                 dev.coherent_dma_mask;
548                         if ((ret = platform_device_add_data(usb_dev_dr_host,
549                                                 &usb_data, sizeof(struct
550                                                 fsl_usb2_platform_data))))
551                                 goto unreg_dr;
552                 }
553                 if (usb_dev_dr_client) {
554                         usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
555                         usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
556                                 dev.coherent_dma_mask;
557                         if ((ret = platform_device_add_data(usb_dev_dr_client,
558                                                 &usb_data, sizeof(struct
559                                                 fsl_usb2_platform_data))))
560                                 goto unreg_dr;
561                 }
562         }
563         return 0;
564
565 unreg_dr:
566         if (usb_dev_dr_host)
567                 platform_device_unregister(usb_dev_dr_host);
568         if (usb_dev_dr_client)
569                 platform_device_unregister(usb_dev_dr_client);
570 unreg_mph:
571         if (usb_dev_mph)
572                 platform_device_unregister(usb_dev_mph);
573 err:
574         return ret;
575 }
576
577 arch_initcall(fsl_usb_of_init);
578
579 #ifdef CONFIG_CPM2
580
581 extern void init_scc_ioports(struct fs_uart_platform_info*);
582
583 static const char fcc_regs[] = "fcc_regs";
584 static const char fcc_regs_c[] = "fcc_regs_c";
585 static const char fcc_pram[] = "fcc_pram";
586 static char bus_id[9][BUS_ID_SIZE];
587
588 static int __init fs_enet_of_init(void)
589 {
590         struct device_node *np;
591         unsigned int i;
592         struct platform_device *fs_enet_dev;
593         struct resource res;
594         int ret;
595
596         for (np = NULL, i = 0;
597              (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
598              i++) {
599                 struct resource r[4];
600                 struct device_node *phy, *mdio;
601                 struct fs_platform_info fs_enet_data;
602                 const unsigned int *id, *phy_addr, *phy_irq;
603                 const void *mac_addr;
604                 const phandle *ph;
605                 const char *model;
606
607                 memset(r, 0, sizeof(r));
608                 memset(&fs_enet_data, 0, sizeof(fs_enet_data));
609
610                 ret = of_address_to_resource(np, 0, &r[0]);
611                 if (ret)
612                         goto err;
613                 r[0].name = fcc_regs;
614
615                 ret = of_address_to_resource(np, 1, &r[1]);
616                 if (ret)
617                         goto err;
618                 r[1].name = fcc_pram;
619
620                 ret = of_address_to_resource(np, 2, &r[2]);
621                 if (ret)
622                         goto err;
623                 r[2].name = fcc_regs_c;
624                 fs_enet_data.fcc_regs_c = r[2].start;
625
626                 of_irq_to_resource(np, 0, &r[3]);
627
628                 fs_enet_dev =
629                     platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
630
631                 if (IS_ERR(fs_enet_dev)) {
632                         ret = PTR_ERR(fs_enet_dev);
633                         goto err;
634                 }
635
636                 model = get_property(np, "model", NULL);
637                 if (model == NULL) {
638                         ret = -ENODEV;
639                         goto unreg;
640                 }
641
642                 mac_addr = of_get_mac_address(np);
643                 if (mac_addr)
644                         memcpy(fs_enet_data.macaddr, mac_addr, 6);
645
646                 ph = get_property(np, "phy-handle", NULL);
647                 phy = of_find_node_by_phandle(*ph);
648
649                 if (phy == NULL) {
650                         ret = -ENODEV;
651                         goto unreg;
652                 }
653
654                 phy_addr = get_property(phy, "reg", NULL);
655                 fs_enet_data.phy_addr = *phy_addr;
656
657                 phy_irq = get_property(phy, "interrupts", NULL);
658
659                 id = get_property(np, "device-id", NULL);
660                 fs_enet_data.fs_no = *id;
661                 strcpy(fs_enet_data.fs_type, model);
662
663                 mdio = of_get_parent(phy);
664                 ret = of_address_to_resource(mdio, 0, &res);
665                 if (ret) {
666                         of_node_put(phy);
667                         of_node_put(mdio);
668                         goto unreg;
669                 }
670
671                 fs_enet_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
672                 fs_enet_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
673
674                 if (strstr(model, "FCC")) {
675                         int fcc_index = *id - 1;
676                         const unsigned char *mdio_bb_prop;
677
678                         fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
679                         fs_enet_data.rx_ring = 32;
680                         fs_enet_data.tx_ring = 32;
681                         fs_enet_data.rx_copybreak = 240;
682                         fs_enet_data.use_napi = 0;
683                         fs_enet_data.napi_weight = 17;
684                         fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
685                         fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
686                         fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index);
687
688                         snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x",
689                                                         (u32)res.start, fs_enet_data.phy_addr);
690                         fs_enet_data.bus_id = (char*)&bus_id[(*id)];
691                         fs_enet_data.init_ioports = init_fcc_ioports;
692
693                         mdio_bb_prop = get_property(phy, "bitbang", NULL);
694                         if (mdio_bb_prop) {
695                                 struct platform_device *fs_enet_mdio_bb_dev;
696                                 struct fs_mii_bb_platform_info fs_enet_mdio_bb_data;
697
698                                 fs_enet_mdio_bb_dev =
699                                         platform_device_register_simple("fsl-bb-mdio",
700                                                         i, NULL, 0);
701                                 memset(&fs_enet_mdio_bb_data, 0,
702                                                 sizeof(struct fs_mii_bb_platform_info));
703                                 fs_enet_mdio_bb_data.mdio_dat.bit =
704                                         mdio_bb_prop[0];
705                                 fs_enet_mdio_bb_data.mdio_dir.bit =
706                                         mdio_bb_prop[1];
707                                 fs_enet_mdio_bb_data.mdc_dat.bit =
708                                         mdio_bb_prop[2];
709                                 fs_enet_mdio_bb_data.mdio_port =
710                                         mdio_bb_prop[3];
711                                 fs_enet_mdio_bb_data.mdc_port =
712                                         mdio_bb_prop[4];
713                                 fs_enet_mdio_bb_data.delay =
714                                         mdio_bb_prop[5];
715
716                                 fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
717                                 fs_enet_mdio_bb_data.irq[1] = -1;
718                                 fs_enet_mdio_bb_data.irq[2] = -1;
719                                 fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
720                                 fs_enet_mdio_bb_data.irq[31] = -1;
721
722                                 fs_enet_mdio_bb_data.mdio_dat.offset =
723                                         (u32)&cpm2_immr->im_ioport.iop_pdatc;
724                                 fs_enet_mdio_bb_data.mdio_dir.offset =
725                                         (u32)&cpm2_immr->im_ioport.iop_pdirc;
726                                 fs_enet_mdio_bb_data.mdc_dat.offset =
727                                         (u32)&cpm2_immr->im_ioport.iop_pdatc;
728
729                                 ret = platform_device_add_data(
730                                                 fs_enet_mdio_bb_dev,
731                                                 &fs_enet_mdio_bb_data,
732                                                 sizeof(struct fs_mii_bb_platform_info));
733                                 if (ret)
734                                         goto unreg;
735                         }
736
737                         of_node_put(phy);
738                         of_node_put(mdio);
739
740                         ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
741                                                      sizeof(struct
742                                                             fs_platform_info));
743                         if (ret)
744                                 goto unreg;
745                 }
746         }
747         return 0;
748
749 unreg:
750         platform_device_unregister(fs_enet_dev);
751 err:
752         return ret;
753 }
754
755 arch_initcall(fs_enet_of_init);
756
757 static const char scc_regs[] = "regs";
758 static const char scc_pram[] = "pram";
759
760 static int __init cpm_uart_of_init(void)
761 {
762         struct device_node *np;
763         unsigned int i;
764         struct platform_device *cpm_uart_dev;
765         int ret;
766
767         for (np = NULL, i = 0;
768              (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
769              i++) {
770                 struct resource r[3];
771                 struct fs_uart_platform_info cpm_uart_data;
772                 const int *id;
773                 const char *model;
774
775                 memset(r, 0, sizeof(r));
776                 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
777
778                 ret = of_address_to_resource(np, 0, &r[0]);
779                 if (ret)
780                         goto err;
781
782                 r[0].name = scc_regs;
783
784                 ret = of_address_to_resource(np, 1, &r[1]);
785                 if (ret)
786                         goto err;
787                 r[1].name = scc_pram;
788
789                 of_irq_to_resource(np, 0, &r[2]);
790
791                 cpm_uart_dev =
792                     platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
793
794                 if (IS_ERR(cpm_uart_dev)) {
795                         ret = PTR_ERR(cpm_uart_dev);
796                         goto err;
797                 }
798
799                 id = get_property(np, "device-id", NULL);
800                 cpm_uart_data.fs_no = *id;
801
802                 model = (char*)get_property(np, "model", NULL);
803                 strcpy(cpm_uart_data.fs_type, model);
804
805                 cpm_uart_data.uart_clk = ppc_proc_freq;
806
807                 cpm_uart_data.tx_num_fifo = 4;
808                 cpm_uart_data.tx_buf_size = 32;
809                 cpm_uart_data.rx_num_fifo = 4;
810                 cpm_uart_data.rx_buf_size = 32;
811                 cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
812                 cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
813
814                 ret =
815                     platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
816                                              sizeof(struct
817                                                     fs_uart_platform_info));
818                 if (ret)
819                         goto unreg;
820         }
821
822         return 0;
823
824 unreg:
825         platform_device_unregister(cpm_uart_dev);
826 err:
827         return ret;
828 }
829
830 arch_initcall(cpm_uart_of_init);
831 #endif /* CONFIG_CPM2 */
832
833 #ifdef CONFIG_8xx
834
835 extern void init_scc_ioports(struct fs_platform_info*);
836 extern int platform_device_skip(char *model, int id);
837
838 static int __init fs_enet_mdio_of_init(void)
839 {
840         struct device_node *np;
841         unsigned int i;
842         struct platform_device *mdio_dev;
843         struct resource res;
844         int ret;
845
846         for (np = NULL, i = 0;
847              (np = of_find_compatible_node(np, "mdio", "fs_enet")) != NULL;
848              i++) {
849                 struct fs_mii_fec_platform_info mdio_data;
850
851                 memset(&res, 0, sizeof(res));
852                 memset(&mdio_data, 0, sizeof(mdio_data));
853
854                 ret = of_address_to_resource(np, 0, &res);
855                 if (ret)
856                         goto err;
857
858                 mdio_dev =
859                     platform_device_register_simple("fsl-cpm-fec-mdio",
860                                                     res.start, &res, 1);
861                 if (IS_ERR(mdio_dev)) {
862                         ret = PTR_ERR(mdio_dev);
863                         goto err;
864                 }
865
866                 mdio_data.mii_speed = ((((ppc_proc_freq + 4999999) / 2500000) / 2) & 0x3F) << 1;
867
868                 ret =
869                     platform_device_add_data(mdio_dev, &mdio_data,
870                                              sizeof(struct fs_mii_fec_platform_info));
871                 if (ret)
872                         goto unreg;
873         }
874         return 0;
875
876 unreg:
877         platform_device_unregister(mdio_dev);
878 err:
879         return ret;
880 }
881
882 arch_initcall(fs_enet_mdio_of_init);
883
884 static const char *enet_regs = "regs";
885 static const char *enet_pram = "pram";
886 static const char *enet_irq = "interrupt";
887 static char bus_id[9][BUS_ID_SIZE];
888
889 static int __init fs_enet_of_init(void)
890 {
891         struct device_node *np;
892         unsigned int i;
893         struct platform_device *fs_enet_dev = NULL;
894         struct resource res;
895         int ret;
896
897         for (np = NULL, i = 0;
898              (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL;
899              i++) {
900                 struct resource r[4];
901                 struct device_node *phy = NULL, *mdio = NULL;
902                 struct fs_platform_info fs_enet_data;
903                 unsigned int *id, *phy_addr;
904                 void *mac_addr;
905                 phandle *ph;
906                 char *model;
907
908                 memset(r, 0, sizeof(r));
909                 memset(&fs_enet_data, 0, sizeof(fs_enet_data));
910
911                 model = (char *)get_property(np, "model", NULL);
912                 if (model == NULL) {
913                         ret = -ENODEV;
914                         goto unreg;
915                 }
916
917                 id = (u32 *) get_property(np, "device-id", NULL);
918                 fs_enet_data.fs_no = *id;
919
920                 if (platform_device_skip(model, *id))
921                         continue;
922
923                 ret = of_address_to_resource(np, 0, &r[0]);
924                 if (ret)
925                         goto err;
926                 r[0].name = enet_regs;
927
928                 mac_addr = of_get_mac_address(np);
929                 if (mac_addr)
930                         memcpy(fs_enet_data.macaddr, mac_addr, 6);
931
932                 ph = (phandle *) get_property(np, "phy-handle", NULL);
933                 if (ph != NULL)
934                         phy = of_find_node_by_phandle(*ph);
935
936                 if (phy != NULL) {
937                         phy_addr = (u32 *) get_property(phy, "reg", NULL);
938                         fs_enet_data.phy_addr = *phy_addr;
939                         fs_enet_data.has_phy = 1;
940
941                         mdio = of_get_parent(phy);
942                         ret = of_address_to_resource(mdio, 0, &res);
943                         if (ret) {
944                                 of_node_put(phy);
945                                 of_node_put(mdio);
946                                 goto unreg;
947                         }
948                 }
949
950                 model = (char*)get_property(np, "model", NULL);
951                 strcpy(fs_enet_data.fs_type, model);
952
953                 if (strstr(model, "FEC")) {
954                         r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
955                         r[1].flags = IORESOURCE_IRQ;
956                         r[1].name = enet_irq;
957
958                         fs_enet_dev =
959                                     platform_device_register_simple("fsl-cpm-fec", i, &r[0], 2);
960
961                         if (IS_ERR(fs_enet_dev)) {
962                                 ret = PTR_ERR(fs_enet_dev);
963                                 goto err;
964                         }
965
966                         fs_enet_data.rx_ring = 128;
967                         fs_enet_data.tx_ring = 16;
968                         fs_enet_data.rx_copybreak = 240;
969                         fs_enet_data.use_napi = 1;
970                         fs_enet_data.napi_weight = 17;
971
972                         snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%x:%02x",
973                                                         (u32)res.start, fs_enet_data.phy_addr);
974                         fs_enet_data.bus_id = (char*)&bus_id[i];
975                         fs_enet_data.init_ioports = init_fec_ioports;
976                 }
977                 if (strstr(model, "SCC")) {
978                         ret = of_address_to_resource(np, 1, &r[1]);
979                         if (ret)
980                                 goto err;
981                         r[1].name = enet_pram;
982
983                         r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
984                         r[2].flags = IORESOURCE_IRQ;
985                         r[2].name = enet_irq;
986
987                         fs_enet_dev =
988                                     platform_device_register_simple("fsl-cpm-scc", i, &r[0], 3);
989
990                         if (IS_ERR(fs_enet_dev)) {
991                                 ret = PTR_ERR(fs_enet_dev);
992                                 goto err;
993                         }
994
995                         fs_enet_data.rx_ring = 64;
996                         fs_enet_data.tx_ring = 8;
997                         fs_enet_data.rx_copybreak = 240;
998                         fs_enet_data.use_napi = 1;
999                         fs_enet_data.napi_weight = 17;
1000
1001                         snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%s", "fixed@10:1");
1002                         fs_enet_data.bus_id = (char*)&bus_id[i];
1003                         fs_enet_data.init_ioports = init_scc_ioports;
1004                 }
1005
1006                 of_node_put(phy);
1007                 of_node_put(mdio);
1008
1009                 ret = platform_device_add_data(fs_enet_dev, &fs_enet_data,
1010                                              sizeof(struct
1011                                                     fs_platform_info));
1012                 if (ret)
1013                         goto unreg;
1014         }
1015         return 0;
1016
1017 unreg:
1018         platform_device_unregister(fs_enet_dev);
1019 err:
1020         return ret;
1021 }
1022
1023 arch_initcall(fs_enet_of_init);
1024
1025
1026 static const char *smc_regs = "regs";
1027 static const char *smc_pram = "pram";
1028
1029 static int __init cpm_smc_uart_of_init(void)
1030 {
1031         struct device_node *np;
1032         unsigned int i;
1033         struct platform_device *cpm_uart_dev;
1034         int ret;
1035
1036         for (np = NULL, i = 0;
1037              (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
1038              i++) {
1039                 struct resource r[3];
1040                 struct fs_uart_platform_info cpm_uart_data;
1041                 int *id;
1042                 char *model;
1043
1044                 memset(r, 0, sizeof(r));
1045                 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
1046
1047                 ret = of_address_to_resource(np, 0, &r[0]);
1048                 if (ret)
1049                         goto err;
1050
1051                 r[0].name = smc_regs;
1052
1053                 ret = of_address_to_resource(np, 1, &r[1]);
1054                 if (ret)
1055                         goto err;
1056                 r[1].name = smc_pram;
1057
1058                 r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
1059                 r[2].flags = IORESOURCE_IRQ;
1060
1061                 cpm_uart_dev =
1062                     platform_device_register_simple("fsl-cpm-smc:uart", i, &r[0], 3);
1063
1064                 if (IS_ERR(cpm_uart_dev)) {
1065                         ret = PTR_ERR(cpm_uart_dev);
1066                         goto err;
1067                 }
1068
1069                 model = (char*)get_property(np, "model", NULL);
1070                 strcpy(cpm_uart_data.fs_type, model);
1071
1072                 id = (int*)get_property(np, "device-id", NULL);
1073                 cpm_uart_data.fs_no = *id;
1074                 cpm_uart_data.uart_clk = ppc_proc_freq;
1075
1076                 cpm_uart_data.tx_num_fifo = 4;
1077                 cpm_uart_data.tx_buf_size = 32;
1078                 cpm_uart_data.rx_num_fifo = 4;
1079                 cpm_uart_data.rx_buf_size = 32;
1080
1081                 ret =
1082                     platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
1083                                              sizeof(struct
1084                                                     fs_uart_platform_info));
1085                 if (ret)
1086                         goto unreg;
1087         }
1088
1089         return 0;
1090
1091 unreg:
1092         platform_device_unregister(cpm_uart_dev);
1093 err:
1094         return ret;
1095 }
1096
1097 arch_initcall(cpm_smc_uart_of_init);
1098
1099 #endif /* CONFIG_8xx */