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