Merge ../linux-2.6-watchdog-mm
[linux-drm-fsl-dcu.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/fsl_devices.h>
26 #include <linux/fs_enet_pd.h>
27 #include <linux/fs_uart_pd.h>
28
29 #include <asm/system.h>
30 #include <asm/atomic.h>
31 #include <asm/io.h>
32 #include <asm/irq.h>
33 #include <asm/time.h>
34 #include <asm/prom.h>
35 #include <sysdev/fsl_soc.h>
36 #include <mm/mmu_decl.h>
37 #include <asm/cpm2.h>
38
39 extern void init_fcc_ioports(struct fs_platform_info*);
40 extern void init_scc_ioports(struct fs_uart_platform_info*);
41 static phys_addr_t immrbase = -1;
42
43 phys_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");
51         if (soc) {
52                 unsigned int size;
53                 const void *prop = get_property(soc, "reg", &size);
54
55                 if (prop)
56                         immrbase = of_translate_address(soc, prop);
57                 of_node_put(soc);
58         };
59
60         return immrbase;
61 }
62
63 EXPORT_SYMBOL(get_immrbase);
64
65 #ifdef CONFIG_CPM2
66
67 static u32 brgfreq = -1;
68
69 u32 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
90 EXPORT_SYMBOL(get_brgfreq);
91
92 static u32 fs_baudrate = -1;
93
94 u32 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
115 EXPORT_SYMBOL(get_baudrate);
116 #endif /* CONFIG_CPM2 */
117
118 static int __init gfar_mdio_of_init(void)
119 {
120         struct device_node *np;
121         unsigned int i;
122         struct platform_device *mdio_dev;
123         struct resource res;
124         int ret;
125
126         for (np = NULL, i = 0;
127              (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
128              i++) {
129                 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)
138                         goto err;
139
140                 mdio_dev =
141                     platform_device_register_simple("fsl-gianfar_mdio",
142                                                     res.start, &res, 1);
143                 if (IS_ERR(mdio_dev)) {
144                         ret = PTR_ERR(mdio_dev);
145                         goto err;
146                 }
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) {
152                         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                         }
157                 }
158
159                 ret =
160                     platform_device_add_data(mdio_dev, &mdio_data,
161                                              sizeof(struct gianfar_mdio_data));
162                 if (ret)
163                         goto unreg;
164         }
165
166         return 0;
167
168 unreg:
169         platform_device_unregister(mdio_dev);
170 err:
171         return ret;
172 }
173
174 arch_initcall(gfar_mdio_of_init);
175
176 static const char *gfar_tx_intr = "tx";
177 static const char *gfar_rx_intr = "rx";
178 static const char *gfar_err_intr = "error";
179
180 static 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++) {
191                 struct resource r[4];
192                 struct device_node *phy, *mdio;
193                 struct gianfar_platform_data gfar_data;
194                 const unsigned int *id;
195                 const char *model;
196                 const void *mac_addr;
197                 const phandle *ph;
198                 int n_res = 2;
199
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)
205                         goto err;
206
207                 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
208                 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;
217                         r[2].start = r[2].end = irq_of_parse_and_map(np, 1);
218                         r[2].flags = IORESOURCE_IRQ;
219
220                         r[3].name = gfar_err_intr;
221                         r[3].start = r[3].end = irq_of_parse_and_map(np, 2);
222                         r[3].flags = IORESOURCE_IRQ;
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 = 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);
246
247                 if (model && !strcasecmp(model, "TSEC"))
248                         gfar_data.device_flags =
249                             FSL_GIANFAR_DEV_HAS_GIGABIT |
250                             FSL_GIANFAR_DEV_HAS_COALESCE |
251                             FSL_GIANFAR_DEV_HAS_RMON |
252                             FSL_GIANFAR_DEV_HAS_MULTI_INTR;
253                 if (model && !strcasecmp(model, "eTSEC"))
254                         gfar_data.device_flags =
255                             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;
262
263                 ph = get_property(np, "phy-handle", NULL);
264                 phy = of_find_node_by_phandle(*ph);
265
266                 if (phy == NULL) {
267                         ret = -ENODEV;
268                         goto unreg;
269                 }
270
271                 mdio = of_get_parent(phy);
272
273                 id = get_property(phy, "reg", NULL);
274                 ret = of_address_to_resource(mdio, 0, &res);
275                 if (ret) {
276                         of_node_put(phy);
277                         of_node_put(mdio);
278                         goto unreg;
279                 }
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
287                 ret =
288                     platform_device_add_data(gfar_dev, &gfar_data,
289                                              sizeof(struct
290                                                     gianfar_platform_data));
291                 if (ret)
292                         goto unreg;
293         }
294
295         return 0;
296
297 unreg:
298         platform_device_unregister(gfar_dev);
299 err:
300         return ret;
301 }
302
303 arch_initcall(gfar_of_init);
304
305 static 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
312         for (np = NULL, i = 0;
313              (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
314              i++) {
315                 struct resource r[2];
316                 struct fsl_i2c_platform_data i2c_data;
317                 const unsigned char *flags = NULL;
318
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)
324                         goto err;
325
326                 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
327                 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);
332                         goto err;
333                 }
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
344                 ret =
345                     platform_device_add_data(i2c_dev, &i2c_data,
346                                              sizeof(struct
347                                                     fsl_i2c_platform_data));
348                 if (ret)
349                         goto unreg;
350         }
351
352         return 0;
353
354 unreg:
355         platform_device_unregister(i2c_dev);
356 err:
357         return ret;
358 }
359
360 arch_initcall(fsl_i2c_of_init);
361
362 #ifdef CONFIG_PPC_83xx
363 static int __init mpc83xx_wdt_init(void)
364 {
365         struct resource r;
366         struct device_node *soc, *np;
367         struct platform_device *dev;
368         const unsigned int *freq;
369         int ret;
370
371         np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
372
373         if (!np) {
374                 ret = -ENODEV;
375                 goto nodev;
376         }
377
378         soc = of_find_node_by_type(NULL, "soc");
379
380         if (!soc) {
381                 ret = -ENODEV;
382                 goto nosoc;
383         }
384
385         freq = get_property(soc, "bus-frequency", NULL);
386         if (!freq) {
387                 ret = -ENODEV;
388                 goto err;
389         }
390
391         memset(&r, 0, sizeof(r));
392
393         ret = of_address_to_resource(np, 0, &r);
394         if (ret)
395                 goto err;
396
397         dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
398         if (IS_ERR(dev)) {
399                 ret = PTR_ERR(dev);
400                 goto err;
401         }
402
403         ret = platform_device_add_data(dev, freq, sizeof(int));
404         if (ret)
405                 goto unreg;
406
407         of_node_put(soc);
408         of_node_put(np);
409
410         return 0;
411
412 unreg:
413         platform_device_unregister(dev);
414 err:
415         of_node_put(soc);
416 nosoc:
417         of_node_put(np);
418 nodev:
419         return ret;
420 }
421
422 arch_initcall(mpc83xx_wdt_init);
423 #endif
424
425 static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
426 {
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
441 static int __init fsl_usb_of_init(void)
442 {
443         struct device_node *np;
444         unsigned int i;
445         struct platform_device *usb_dev_mph = NULL, *usb_dev_dr = NULL;
446         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;
453                 const unsigned char *prop = NULL;
454
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
462                 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
463                 r[1].flags = IORESOURCE_IRQ;
464
465                 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);
469                         goto err;
470                 }
471
472                 usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
473                 usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
474
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 =
489                     platform_device_add_data(usb_dev_mph, &usb_data,
490                                              sizeof(struct
491                                                     fsl_usb2_platform_data));
492                 if (ret)
493                         goto unreg_mph;
494         }
495
496         for (np = NULL;
497              (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;
501                 const unsigned char *prop = NULL;
502
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)
508                         goto unreg_mph;
509
510                 r[1].start = r[1].end = irq_of_parse_and_map(np, 0);
511                 r[1].flags = IORESOURCE_IRQ;
512
513                 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);
517                         goto err;
518                 }
519
520                 usb_dev_dr->dev.coherent_dma_mask = 0xffffffffUL;
521                 usb_dev_dr->dev.dma_mask = &usb_dev_dr->dev.coherent_dma_mask;
522
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 =
529                     platform_device_add_data(usb_dev_dr, &usb_data,
530                                              sizeof(struct
531                                                     fsl_usb2_platform_data));
532                 if (ret)
533                         goto unreg_dr;
534         }
535         return 0;
536
537 unreg_dr:
538         if (usb_dev_dr)
539                 platform_device_unregister(usb_dev_dr);
540 unreg_mph:
541         if (usb_dev_mph)
542                 platform_device_unregister(usb_dev_mph);
543 err:
544         return ret;
545 }
546
547 arch_initcall(fsl_usb_of_init);
548
549 #ifdef CONFIG_CPM2
550
551 static const char fcc_regs[] = "fcc_regs";
552 static const char fcc_regs_c[] = "fcc_regs_c";
553 static const char fcc_pram[] = "fcc_pram";
554 static char bus_id[9][BUS_ID_SIZE];
555
556 static 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;
570                 const unsigned int *id, *phy_addr, *phy_irq;
571                 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;
592                 fs_enet_data.fcc_regs_c = r[2].start;
593
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
625                 phy_irq = get_property(phy, "interrupts", NULL);
626
627                 id = get_property(np, "device-id", NULL);
628                 fs_enet_data.fs_no = *id;
629                 strcpy(fs_enet_data.fs_type, model);
630
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
639                 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
642                 if (strstr(model, "FCC")) {
643                         int fcc_index = *id - 1;
644                         const unsigned char *mdio_bb_prop;
645
646                         fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0);
647                         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)];
659                         fs_enet_data.init_ioports = init_fcc_ioports;
660
661                         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;
665
666                                 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));
711                         if (ret)
712                                 goto unreg;
713                 }
714         }
715         return 0;
716
717 unreg:
718         platform_device_unregister(fs_enet_dev);
719 err:
720         return ret;
721 }
722
723 arch_initcall(fs_enet_of_init);
724
725 static const char scc_regs[] = "regs";
726 static const char scc_pram[] = "pram";
727
728 static int __init cpm_uart_of_init(void)
729 {
730         struct device_node *np;
731         unsigned int i;
732         struct platform_device *cpm_uart_dev;
733         int ret;
734
735         for (np = NULL, i = 0;
736              (np = of_find_compatible_node(np, "serial", "cpm_uart")) != NULL;
737              i++) {
738                 struct resource r[3];
739                 struct fs_uart_platform_info cpm_uart_data;
740                 const int *id;
741                 const char *model;
742
743                 memset(r, 0, sizeof(r));
744                 memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
745
746                 ret = of_address_to_resource(np, 0, &r[0]);
747                 if (ret)
748                         goto err;
749
750                 r[0].name = scc_regs;
751
752                 ret = of_address_to_resource(np, 1, &r[1]);
753                 if (ret)
754                         goto err;
755                 r[1].name = scc_pram;
756
757                 r[2].start = r[2].end = irq_of_parse_and_map(np, 0);
758                 r[2].flags = IORESOURCE_IRQ;
759
760                 cpm_uart_dev =
761                     platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
762
763                 if (IS_ERR(cpm_uart_dev)) {
764                         ret = PTR_ERR(cpm_uart_dev);
765                         goto err;
766                 }
767
768                 id = get_property(np, "device-id", NULL);
769                 cpm_uart_data.fs_no = *id;
770
771                 model = (char*)get_property(np, "model", NULL);
772                 strcpy(cpm_uart_data.fs_type, model);
773
774                 cpm_uart_data.uart_clk = ppc_proc_freq;
775
776                 cpm_uart_data.tx_num_fifo = 4;
777                 cpm_uart_data.tx_buf_size = 32;
778                 cpm_uart_data.rx_num_fifo = 4;
779                 cpm_uart_data.rx_buf_size = 32;
780                 cpm_uart_data.clk_rx = *((u32 *) get_property(np, "rx-clock", NULL));
781                 cpm_uart_data.clk_tx = *((u32 *) get_property(np, "tx-clock", NULL));
782
783                 ret =
784                     platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
785                                              sizeof(struct
786                                                     fs_uart_platform_info));
787                 if (ret)
788                         goto unreg;
789         }
790
791         return 0;
792
793 unreg:
794         platform_device_unregister(cpm_uart_dev);
795 err:
796         return ret;
797 }
798
799 arch_initcall(cpm_uart_of_init);
800 #endif /* CONFIG_CPM2 */