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