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