Merge remote-tracking branch 'upstream' into next
[cascardo/linux.git] / arch / mips / bcm63xx / boards / board_bcm963xx.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7  * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
8  */
9
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/platform_device.h>
14 #include <linux/ssb/ssb.h>
15 #include <asm/addrspace.h>
16 #include <bcm63xx_board.h>
17 #include <bcm63xx_cpu.h>
18 #include <bcm63xx_dev_uart.h>
19 #include <bcm63xx_regs.h>
20 #include <bcm63xx_io.h>
21 #include <bcm63xx_dev_pci.h>
22 #include <bcm63xx_dev_enet.h>
23 #include <bcm63xx_dev_dsp.h>
24 #include <bcm63xx_dev_flash.h>
25 #include <bcm63xx_dev_pcmcia.h>
26 #include <bcm63xx_dev_spi.h>
27 #include <board_bcm963xx.h>
28
29 #define PFX     "board_bcm963xx: "
30
31 static struct bcm963xx_nvram nvram;
32 static unsigned int mac_addr_used;
33 static struct board_info board;
34
35 /*
36  * known 6328 boards
37  */
38 #ifdef CONFIG_BCM63XX_CPU_6328
39 static struct board_info __initdata board_96328avng = {
40         .name                           = "96328avng",
41         .expected_cpu_id                = 0x6328,
42
43         .has_uart0                      = 1,
44         .has_pci                        = 1,
45
46         .leds = {
47                 {
48                         .name           = "96328avng::ppp-fail",
49                         .gpio           = 2,
50                         .active_low     = 1,
51                 },
52                 {
53                         .name           = "96328avng::power",
54                         .gpio           = 4,
55                         .active_low     = 1,
56                         .default_trigger = "default-on",
57                 },
58                 {
59                         .name           = "96328avng::power-fail",
60                         .gpio           = 8,
61                         .active_low     = 1,
62                 },
63                 {
64                         .name           = "96328avng::wps",
65                         .gpio           = 9,
66                         .active_low     = 1,
67                 },
68                 {
69                         .name           = "96328avng::ppp",
70                         .gpio           = 11,
71                         .active_low     = 1,
72                 },
73         },
74 };
75 #endif
76
77 /*
78  * known 6338 boards
79  */
80 #ifdef CONFIG_BCM63XX_CPU_6338
81 static struct board_info __initdata board_96338gw = {
82         .name                           = "96338GW",
83         .expected_cpu_id                = 0x6338,
84
85         .has_uart0                      = 1,
86         .has_enet0                      = 1,
87         .enet0 = {
88                 .force_speed_100        = 1,
89                 .force_duplex_full      = 1,
90         },
91
92         .has_ohci0                      = 1,
93
94         .leds = {
95                 {
96                         .name           = "adsl",
97                         .gpio           = 3,
98                         .active_low     = 1,
99                 },
100                 {
101                         .name           = "ses",
102                         .gpio           = 5,
103                         .active_low     = 1,
104                 },
105                 {
106                         .name           = "ppp-fail",
107                         .gpio           = 4,
108                         .active_low     = 1,
109                 },
110                 {
111                         .name           = "power",
112                         .gpio           = 0,
113                         .active_low     = 1,
114                         .default_trigger = "default-on",
115                 },
116                 {
117                         .name           = "stop",
118                         .gpio           = 1,
119                         .active_low     = 1,
120                 }
121         },
122 };
123
124 static struct board_info __initdata board_96338w = {
125         .name                           = "96338W",
126         .expected_cpu_id                = 0x6338,
127
128         .has_uart0                      = 1,
129         .has_enet0                      = 1,
130         .enet0 = {
131                 .force_speed_100        = 1,
132                 .force_duplex_full      = 1,
133         },
134
135         .leds = {
136                 {
137                         .name           = "adsl",
138                         .gpio           = 3,
139                         .active_low     = 1,
140                 },
141                 {
142                         .name           = "ses",
143                         .gpio           = 5,
144                         .active_low     = 1,
145                 },
146                 {
147                         .name           = "ppp-fail",
148                         .gpio           = 4,
149                         .active_low     = 1,
150                 },
151                 {
152                         .name           = "power",
153                         .gpio           = 0,
154                         .active_low     = 1,
155                         .default_trigger = "default-on",
156                 },
157                 {
158                         .name           = "stop",
159                         .gpio           = 1,
160                         .active_low     = 1,
161                 },
162         },
163 };
164 #endif
165
166 /*
167  * known 6345 boards
168  */
169 #ifdef CONFIG_BCM63XX_CPU_6345
170 static struct board_info __initdata board_96345gw2 = {
171         .name                           = "96345GW2",
172         .expected_cpu_id                = 0x6345,
173
174         .has_uart0                      = 1,
175 };
176 #endif
177
178 /*
179  * known 6348 boards
180  */
181 #ifdef CONFIG_BCM63XX_CPU_6348
182 static struct board_info __initdata board_96348r = {
183         .name                           = "96348R",
184         .expected_cpu_id                = 0x6348,
185
186         .has_uart0                      = 1,
187         .has_enet0                      = 1,
188         .has_pci                        = 1,
189
190         .enet0 = {
191                 .has_phy                = 1,
192                 .use_internal_phy       = 1,
193         },
194
195         .leds = {
196                 {
197                         .name           = "adsl-fail",
198                         .gpio           = 2,
199                         .active_low     = 1,
200                 },
201                 {
202                         .name           = "ppp",
203                         .gpio           = 3,
204                         .active_low     = 1,
205                 },
206                 {
207                         .name           = "ppp-fail",
208                         .gpio           = 4,
209                         .active_low     = 1,
210                 },
211                 {
212                         .name           = "power",
213                         .gpio           = 0,
214                         .active_low     = 1,
215                         .default_trigger = "default-on",
216
217                 },
218                 {
219                         .name           = "stop",
220                         .gpio           = 1,
221                         .active_low     = 1,
222                 },
223         },
224 };
225
226 static struct board_info __initdata board_96348gw_10 = {
227         .name                           = "96348GW-10",
228         .expected_cpu_id                = 0x6348,
229
230         .has_uart0                      = 1,
231         .has_enet0                      = 1,
232         .has_enet1                      = 1,
233         .has_pci                        = 1,
234
235         .enet0 = {
236                 .has_phy                = 1,
237                 .use_internal_phy       = 1,
238         },
239         .enet1 = {
240                 .force_speed_100        = 1,
241                 .force_duplex_full      = 1,
242         },
243
244         .has_ohci0                      = 1,
245         .has_pccard                     = 1,
246         .has_ehci0                      = 1,
247
248         .has_dsp                        = 1,
249         .dsp = {
250                 .gpio_rst               = 6,
251                 .gpio_int               = 34,
252                 .cs                     = 2,
253                 .ext_irq                = 2,
254         },
255
256         .leds = {
257                 {
258                         .name           = "adsl-fail",
259                         .gpio           = 2,
260                         .active_low     = 1,
261                 },
262                 {
263                         .name           = "ppp",
264                         .gpio           = 3,
265                         .active_low     = 1,
266                 },
267                 {
268                         .name           = "ppp-fail",
269                         .gpio           = 4,
270                         .active_low     = 1,
271                 },
272                 {
273                         .name           = "power",
274                         .gpio           = 0,
275                         .active_low     = 1,
276                         .default_trigger = "default-on",
277                 },
278                 {
279                         .name           = "stop",
280                         .gpio           = 1,
281                         .active_low     = 1,
282                 },
283         },
284 };
285
286 static struct board_info __initdata board_96348gw_11 = {
287         .name                           = "96348GW-11",
288         .expected_cpu_id                = 0x6348,
289
290         .has_uart0                      = 1,
291         .has_enet0                      = 1,
292         .has_enet1                      = 1,
293         .has_pci                        = 1,
294
295         .enet0 = {
296                 .has_phy                = 1,
297                 .use_internal_phy       = 1,
298         },
299
300         .enet1 = {
301                 .force_speed_100        = 1,
302                 .force_duplex_full      = 1,
303         },
304
305
306         .has_ohci0 = 1,
307         .has_pccard = 1,
308         .has_ehci0 = 1,
309
310         .leds = {
311                 {
312                         .name           = "adsl-fail",
313                         .gpio           = 2,
314                         .active_low     = 1,
315                 },
316                 {
317                         .name           = "ppp",
318                         .gpio           = 3,
319                         .active_low     = 1,
320                 },
321                 {
322                         .name           = "ppp-fail",
323                         .gpio           = 4,
324                         .active_low     = 1,
325                 },
326                 {
327                         .name           = "power",
328                         .gpio           = 0,
329                         .active_low     = 1,
330                         .default_trigger = "default-on",
331                 },
332                 {
333                         .name           = "stop",
334                         .gpio           = 1,
335                         .active_low     = 1,
336                 },
337         },
338 };
339
340 static struct board_info __initdata board_96348gw = {
341         .name                           = "96348GW",
342         .expected_cpu_id                = 0x6348,
343
344         .has_uart0                      = 1,
345         .has_enet0                      = 1,
346         .has_enet1                      = 1,
347         .has_pci                        = 1,
348
349         .enet0 = {
350                 .has_phy                = 1,
351                 .use_internal_phy       = 1,
352         },
353         .enet1 = {
354                 .force_speed_100        = 1,
355                 .force_duplex_full      = 1,
356         },
357
358         .has_ohci0 = 1,
359
360         .has_dsp                        = 1,
361         .dsp = {
362                 .gpio_rst               = 6,
363                 .gpio_int               = 34,
364                 .ext_irq                = 2,
365                 .cs                     = 2,
366         },
367
368         .leds = {
369                 {
370                         .name           = "adsl-fail",
371                         .gpio           = 2,
372                         .active_low     = 1,
373                 },
374                 {
375                         .name           = "ppp",
376                         .gpio           = 3,
377                         .active_low     = 1,
378                 },
379                 {
380                         .name           = "ppp-fail",
381                         .gpio           = 4,
382                         .active_low     = 1,
383                 },
384                 {
385                         .name           = "power",
386                         .gpio           = 0,
387                         .active_low     = 1,
388                         .default_trigger = "default-on",
389                 },
390                 {
391                         .name           = "stop",
392                         .gpio           = 1,
393                         .active_low     = 1,
394                 },
395         },
396 };
397
398 static struct board_info __initdata board_FAST2404 = {
399         .name                           = "F@ST2404",
400         .expected_cpu_id                = 0x6348,
401
402         .has_uart0                      = 1,
403         .has_enet0                      = 1,
404         .has_enet1                      = 1,
405         .has_pci                        = 1,
406
407         .enet0 = {
408                 .has_phy                = 1,
409                 .use_internal_phy       = 1,
410         },
411
412         .enet1 = {
413                 .force_speed_100        = 1,
414                 .force_duplex_full      = 1,
415         },
416
417         .has_ohci0                      = 1,
418         .has_pccard                     = 1,
419         .has_ehci0                      = 1,
420 };
421
422 static struct board_info __initdata board_rta1025w_16 = {
423         .name                           = "RTA1025W_16",
424         .expected_cpu_id                = 0x6348,
425
426         .has_enet0                      = 1,
427         .has_enet1                      = 1,
428         .has_pci                        = 1,
429
430         .enet0 = {
431                 .has_phy                = 1,
432                 .use_internal_phy       = 1,
433         },
434         .enet1 = {
435                 .force_speed_100        = 1,
436                 .force_duplex_full      = 1,
437         },
438 };
439
440
441 static struct board_info __initdata board_DV201AMR = {
442         .name                           = "DV201AMR",
443         .expected_cpu_id                = 0x6348,
444
445         .has_uart0                      = 1,
446         .has_pci                        = 1,
447         .has_ohci0                      = 1,
448
449         .has_enet0                      = 1,
450         .has_enet1                      = 1,
451         .enet0 = {
452                 .has_phy                = 1,
453                 .use_internal_phy       = 1,
454         },
455         .enet1 = {
456                 .force_speed_100        = 1,
457                 .force_duplex_full      = 1,
458         },
459 };
460
461 static struct board_info __initdata board_96348gw_a = {
462         .name                           = "96348GW-A",
463         .expected_cpu_id                = 0x6348,
464
465         .has_uart0                      = 1,
466         .has_enet0                      = 1,
467         .has_enet1                      = 1,
468         .has_pci                        = 1,
469
470         .enet0 = {
471                 .has_phy                = 1,
472                 .use_internal_phy       = 1,
473         },
474         .enet1 = {
475                 .force_speed_100        = 1,
476                 .force_duplex_full      = 1,
477         },
478
479         .has_ohci0 = 1,
480 };
481 #endif
482
483 /*
484  * known 6358 boards
485  */
486 #ifdef CONFIG_BCM63XX_CPU_6358
487 static struct board_info __initdata board_96358vw = {
488         .name                           = "96358VW",
489         .expected_cpu_id                = 0x6358,
490
491         .has_uart0                      = 1,
492         .has_enet0                      = 1,
493         .has_enet1                      = 1,
494         .has_pci                        = 1,
495
496         .enet0 = {
497                 .has_phy                = 1,
498                 .use_internal_phy       = 1,
499         },
500
501         .enet1 = {
502                 .force_speed_100        = 1,
503                 .force_duplex_full      = 1,
504         },
505
506
507         .has_ohci0 = 1,
508         .has_pccard = 1,
509         .has_ehci0 = 1,
510
511         .leds = {
512                 {
513                         .name           = "adsl-fail",
514                         .gpio           = 15,
515                         .active_low     = 1,
516                 },
517                 {
518                         .name           = "ppp",
519                         .gpio           = 22,
520                         .active_low     = 1,
521                 },
522                 {
523                         .name           = "ppp-fail",
524                         .gpio           = 23,
525                         .active_low     = 1,
526                 },
527                 {
528                         .name           = "power",
529                         .gpio           = 4,
530                         .default_trigger = "default-on",
531                 },
532                 {
533                         .name           = "stop",
534                         .gpio           = 5,
535                 },
536         },
537 };
538
539 static struct board_info __initdata board_96358vw2 = {
540         .name                           = "96358VW2",
541         .expected_cpu_id                = 0x6358,
542
543         .has_uart0                      = 1,
544         .has_enet0                      = 1,
545         .has_enet1                      = 1,
546         .has_pci                        = 1,
547
548         .enet0 = {
549                 .has_phy                = 1,
550                 .use_internal_phy       = 1,
551         },
552
553         .enet1 = {
554                 .force_speed_100        = 1,
555                 .force_duplex_full      = 1,
556         },
557
558
559         .has_ohci0 = 1,
560         .has_pccard = 1,
561         .has_ehci0 = 1,
562
563         .leds = {
564                 {
565                         .name           = "adsl",
566                         .gpio           = 22,
567                         .active_low     = 1,
568                 },
569                 {
570                         .name           = "ppp-fail",
571                         .gpio           = 23,
572                 },
573                 {
574                         .name           = "power",
575                         .gpio           = 5,
576                         .active_low     = 1,
577                         .default_trigger = "default-on",
578                 },
579                 {
580                         .name           = "stop",
581                         .gpio           = 4,
582                         .active_low     = 1,
583                 },
584         },
585 };
586
587 static struct board_info __initdata board_AGPFS0 = {
588         .name                           = "AGPF-S0",
589         .expected_cpu_id                = 0x6358,
590
591         .has_uart0                      = 1,
592         .has_enet0                      = 1,
593         .has_enet1                      = 1,
594         .has_pci                        = 1,
595
596         .enet0 = {
597                 .has_phy                = 1,
598                 .use_internal_phy       = 1,
599         },
600
601         .enet1 = {
602                 .force_speed_100        = 1,
603                 .force_duplex_full      = 1,
604         },
605
606         .has_ohci0 = 1,
607         .has_ehci0 = 1,
608 };
609
610 static struct board_info __initdata board_DWVS0 = {
611         .name                           = "DWV-S0",
612         .expected_cpu_id                = 0x6358,
613
614         .has_enet0                      = 1,
615         .has_enet1                      = 1,
616         .has_pci                        = 1,
617
618         .enet0 = {
619                 .has_phy                = 1,
620                 .use_internal_phy       = 1,
621         },
622
623         .enet1 = {
624                 .force_speed_100        = 1,
625                 .force_duplex_full      = 1,
626         },
627
628         .has_ohci0                      = 1,
629 };
630 #endif
631
632 /*
633  * all boards
634  */
635 static const struct board_info __initdata *bcm963xx_boards[] = {
636 #ifdef CONFIG_BCM63XX_CPU_6328
637         &board_96328avng,
638 #endif
639 #ifdef CONFIG_BCM63XX_CPU_6338
640         &board_96338gw,
641         &board_96338w,
642 #endif
643 #ifdef CONFIG_BCM63XX_CPU_6345
644         &board_96345gw2,
645 #endif
646 #ifdef CONFIG_BCM63XX_CPU_6348
647         &board_96348r,
648         &board_96348gw,
649         &board_96348gw_10,
650         &board_96348gw_11,
651         &board_FAST2404,
652         &board_DV201AMR,
653         &board_96348gw_a,
654         &board_rta1025w_16,
655 #endif
656
657 #ifdef CONFIG_BCM63XX_CPU_6358
658         &board_96358vw,
659         &board_96358vw2,
660         &board_AGPFS0,
661         &board_DWVS0,
662 #endif
663 };
664
665 /*
666  * Register a sane SPROMv2 to make the on-board
667  * bcm4318 WLAN work
668  */
669 #ifdef CONFIG_SSB_PCIHOST
670 static struct ssb_sprom bcm63xx_sprom = {
671         .revision               = 0x02,
672         .board_rev              = 0x17,
673         .country_code           = 0x0,
674         .ant_available_bg       = 0x3,
675         .pa0b0                  = 0x15ae,
676         .pa0b1                  = 0xfa85,
677         .pa0b2                  = 0xfe8d,
678         .pa1b0                  = 0xffff,
679         .pa1b1                  = 0xffff,
680         .pa1b2                  = 0xffff,
681         .gpio0                  = 0xff,
682         .gpio1                  = 0xff,
683         .gpio2                  = 0xff,
684         .gpio3                  = 0xff,
685         .maxpwr_bg              = 0x004c,
686         .itssi_bg               = 0x00,
687         .boardflags_lo          = 0x2848,
688         .boardflags_hi          = 0x0000,
689 };
690
691 int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
692 {
693         if (bus->bustype == SSB_BUSTYPE_PCI) {
694                 memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
695                 return 0;
696         } else {
697                 printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
698                 return -EINVAL;
699         }
700 }
701 #endif
702
703 /*
704  * return board name for /proc/cpuinfo
705  */
706 const char *board_get_name(void)
707 {
708         return board.name;
709 }
710
711 /*
712  * register & return a new board mac address
713  */
714 static int board_get_mac_address(u8 *mac)
715 {
716         u8 *p;
717         int count;
718
719         if (mac_addr_used >= nvram.mac_addr_count) {
720                 printk(KERN_ERR PFX "not enough mac address\n");
721                 return -ENODEV;
722         }
723
724         memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
725         p = mac + ETH_ALEN - 1;
726         count = mac_addr_used;
727
728         while (count--) {
729                 do {
730                         (*p)++;
731                         if (*p != 0)
732                                 break;
733                         p--;
734                 } while (p != mac);
735         }
736
737         if (p == mac) {
738                 printk(KERN_ERR PFX "unable to fetch mac address\n");
739                 return -ENODEV;
740         }
741
742         mac_addr_used++;
743         return 0;
744 }
745
746 /*
747  * early init callback, read nvram data from flash and checksum it
748  */
749 void __init board_prom_init(void)
750 {
751         unsigned int check_len, i;
752         u8 *boot_addr, *cfe, *p;
753         char cfe_version[32];
754         u32 val;
755
756         /* read base address of boot chip select (0)
757          * 6328 does not have MPI but boots from a fixed address
758          */
759         if (BCMCPU_IS_6328())
760                 val = 0x18000000;
761         else {
762                 val = bcm_mpi_readl(MPI_CSBASE_REG(0));
763                 val &= MPI_CSBASE_BASE_MASK;
764         }
765         boot_addr = (u8 *)KSEG1ADDR(val);
766
767         /* dump cfe version */
768         cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
769         if (!memcmp(cfe, "cfe-v", 5))
770                 snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
771                          cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
772         else
773                 strcpy(cfe_version, "unknown");
774         printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
775
776         /* extract nvram data */
777         memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
778
779         /* check checksum before using data */
780         if (nvram.version <= 4)
781                 check_len = offsetof(struct bcm963xx_nvram, checksum_old);
782         else
783                 check_len = sizeof(nvram);
784         val = 0;
785         p = (u8 *)&nvram;
786         while (check_len--)
787                 val += *p;
788         if (val) {
789                 printk(KERN_ERR PFX "invalid nvram checksum\n");
790                 return;
791         }
792
793         /* find board by name */
794         for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
795                 if (strncmp(nvram.name, bcm963xx_boards[i]->name,
796                             sizeof(nvram.name)))
797                         continue;
798                 /* copy, board desc array is marked initdata */
799                 memcpy(&board, bcm963xx_boards[i], sizeof(board));
800                 break;
801         }
802
803         /* bail out if board is not found, will complain later */
804         if (!board.name[0]) {
805                 char name[17];
806                 memcpy(name, nvram.name, 16);
807                 name[16] = 0;
808                 printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
809                        name);
810                 return;
811         }
812
813         /* setup pin multiplexing depending on board enabled device,
814          * this has to be done this early since PCI init is done
815          * inside arch_initcall */
816         val = 0;
817
818 #ifdef CONFIG_PCI
819         if (board.has_pci) {
820                 bcm63xx_pci_enabled = 1;
821                 if (BCMCPU_IS_6348())
822                         val |= GPIO_MODE_6348_G2_PCI;
823         }
824 #endif
825
826         if (board.has_pccard) {
827                 if (BCMCPU_IS_6348())
828                         val |= GPIO_MODE_6348_G1_MII_PCCARD;
829         }
830
831         if (board.has_enet0 && !board.enet0.use_internal_phy) {
832                 if (BCMCPU_IS_6348())
833                         val |= GPIO_MODE_6348_G3_EXT_MII |
834                                 GPIO_MODE_6348_G0_EXT_MII;
835         }
836
837         if (board.has_enet1 && !board.enet1.use_internal_phy) {
838                 if (BCMCPU_IS_6348())
839                         val |= GPIO_MODE_6348_G3_EXT_MII |
840                                 GPIO_MODE_6348_G0_EXT_MII;
841         }
842
843         bcm_gpio_writel(val, GPIO_MODE_REG);
844 }
845
846 /*
847  * second stage init callback, good time to panic if we couldn't
848  * identify on which board we're running since early printk is working
849  */
850 void __init board_setup(void)
851 {
852         if (!board.name[0])
853                 panic("unable to detect bcm963xx board");
854         printk(KERN_INFO PFX "board name: %s\n", board.name);
855
856         /* make sure we're running on expected cpu */
857         if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
858                 panic("unexpected CPU for bcm963xx board");
859 }
860
861 static struct gpio_led_platform_data bcm63xx_led_data;
862
863 static struct platform_device bcm63xx_gpio_leds = {
864         .name                   = "leds-gpio",
865         .id                     = 0,
866         .dev.platform_data      = &bcm63xx_led_data,
867 };
868
869 /*
870  * third stage init callback, register all board devices.
871  */
872 int __init board_register_devices(void)
873 {
874         if (board.has_uart0)
875                 bcm63xx_uart_register(0);
876
877         if (board.has_uart1)
878                 bcm63xx_uart_register(1);
879
880         if (board.has_pccard)
881                 bcm63xx_pcmcia_register();
882
883         if (board.has_enet0 &&
884             !board_get_mac_address(board.enet0.mac_addr))
885                 bcm63xx_enet_register(0, &board.enet0);
886
887         if (board.has_enet1 &&
888             !board_get_mac_address(board.enet1.mac_addr))
889                 bcm63xx_enet_register(1, &board.enet1);
890
891         if (board.has_dsp)
892                 bcm63xx_dsp_register(&board.dsp);
893
894         /* Generate MAC address for WLAN and register our SPROM,
895          * do this after registering enet devices
896          */
897 #ifdef CONFIG_SSB_PCIHOST
898         if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
899                 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
900                 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
901                 if (ssb_arch_register_fallback_sprom(
902                                 &bcm63xx_get_fallback_sprom) < 0)
903                         pr_err(PFX "failed to register fallback SPROM\n");
904         }
905 #endif
906
907         bcm63xx_spi_register();
908
909         bcm63xx_flash_register();
910
911         bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
912         bcm63xx_led_data.leds = board.leds;
913
914         platform_device_register(&bcm63xx_gpio_leds);
915
916         return 0;
917 }