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