cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

board_bcm963xx.c (16258B)


      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
     34static struct board_info board;
     35
     36/*
     37 * known 3368 boards
     38 */
     39#ifdef CONFIG_BCM63XX_CPU_3368
     40static 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
     70static 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
    118static 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
    161static 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
    208static 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
    220static 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
    264static 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
    315static 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
    366static 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
    416static 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
    438static 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
    457static 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
    478static 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
    504static 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
    554static 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
    600static 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
    622static 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 */
    647static 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
    684static 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
    705int 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 */
    720const 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 */
    728void __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 */
    834void __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
    845static struct gpio_led_platform_data bcm63xx_led_data;
    846
    847static 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 */
    856int __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}