From: Hauke Mehrtens Date: Sun, 6 Oct 2013 23:55:35 +0000 (+0000) Subject: brcm47xx: update early printk patches X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=b2018180441b7b51f15bfd74669e21f4a0127f30;p=openwrt%2Fstaging%2Fjow.git brcm47xx: update early printk patches Early printk was disabled because it caused hangs on some devices, the old patches were using the CFE console now we use the normal serial console, it is at a constant address. Signed-off-by: Hauke Mehrtens SVN-Revision: 38309 --- diff --git a/target/linux/brcm47xx/config-3.10 b/target/linux/brcm47xx/config-3.10 index 7518bb80d0..da786412d3 100644 --- a/target/linux/brcm47xx/config-3.10 +++ b/target/linux/brcm47xx/config-3.10 @@ -48,7 +48,8 @@ CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y -CONFIG_FW_CFE=y +CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_8250=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y @@ -148,6 +149,7 @@ CONFIG_SSB_SPROM=y CONFIG_SWCONFIG=y CONFIG_SYS_HAS_CPU_MIPS32_R1=y CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_SYS_HAS_EARLY_PRINTK=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y CONFIG_SYS_SUPPORTS_ARBIT_HZ=y CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y diff --git a/target/linux/brcm47xx/patches-3.10/080-MIPS-Add-8250-16550-serial-early-printk-driver.patch b/target/linux/brcm47xx/patches-3.10/080-MIPS-Add-8250-16550-serial-early-printk-driver.patch new file mode 100644 index 0000000000..bfbe43be5b --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/080-MIPS-Add-8250-16550-serial-early-printk-driver.patch @@ -0,0 +1,124 @@ +commit 0a76092a63809a0e72e3e9552acadf42869c0293 +Author: Yoichi Yuasa +Date: Mon Feb 8 20:59:39 2010 +0900 + + MIPS: Add 8250/16550 serial early printk driver + + Signed-off-by: Yoichi Yuasa + Cc: linux-mips + Patchwork: https://patchwork.linux-mips.org/patch/947/ + Signed-off-by: Ralf Baechle + +--- a/arch/mips/Kconfig.debug ++++ b/arch/mips/Kconfig.debug +@@ -20,6 +20,14 @@ config EARLY_PRINTK + doesn't cooperate with an X server. You should normally say N here, + unless you want to debug such a crash. + ++config EARLY_PRINTK_8250 ++ bool "8250/16550 and compatible serial early printk driver" ++ depends on EARLY_PRINTK ++ default n ++ help ++ If you say Y here, it will be possible to use a 8250/16550 serial ++ port as the boot console. ++ + config CMDLINE_BOOL + bool "Built-in kernel command line" + default n +--- a/arch/mips/include/asm/setup.h ++++ b/arch/mips/include/asm/setup.h +@@ -5,6 +5,14 @@ + + extern void setup_early_printk(void); + ++#ifdef CONFIG_EARLY_PRINTK_8250 ++extern void setup_8250_early_printk_port(unsigned long base, ++ unsigned int reg_shift, unsigned int timeout); ++#else ++static inline void setup_8250_early_printk_port(unsigned long base, ++ unsigned int reg_shift, unsigned int timeout) {} ++#endif ++ + extern void set_handler(unsigned long offset, void *addr, unsigned long len); + extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len); + +--- a/arch/mips/kernel/Makefile ++++ b/arch/mips/kernel/Makefile +@@ -84,6 +84,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o + obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o + obj-$(CONFIG_CRASH_DUMP) += crash_dump.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++obj-$(CONFIG_EARLY_PRINTK_8250) += early_printk_8250.o + obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o + obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o + +--- /dev/null ++++ b/arch/mips/kernel/early_printk_8250.c +@@ -0,0 +1,66 @@ ++/* ++ * 8250/16550-type serial ports prom_putchar() ++ * ++ * Copyright (C) 2010 Yoichi Yuasa ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++#include ++#include ++#include ++ ++static void __iomem *serial8250_base; ++static unsigned int serial8250_reg_shift; ++static unsigned int serial8250_tx_timeout; ++ ++void setup_8250_early_printk_port(unsigned long base, unsigned int reg_shift, ++ unsigned int timeout) ++{ ++ serial8250_base = (void __iomem *)base; ++ serial8250_reg_shift = reg_shift; ++ serial8250_tx_timeout = timeout; ++} ++ ++static inline u8 serial_in(int offset) ++{ ++ return readb(serial8250_base + (offset << serial8250_reg_shift)); ++} ++ ++static inline void serial_out(int offset, char value) ++{ ++ writeb(value, serial8250_base + (offset << serial8250_reg_shift)); ++} ++ ++void prom_putchar(char c) ++{ ++ unsigned int timeout; ++ int status, bits; ++ ++ if (!serial8250_base) ++ return; ++ ++ timeout = serial8250_tx_timeout; ++ bits = UART_LSR_TEMT | UART_LSR_THRE; ++ ++ do { ++ status = serial_in(UART_LSR); ++ ++ if (--timeout == 0) ++ break; ++ } while ((status & bits) != bits); ++ ++ if (timeout) ++ serial_out(UART_TX, c); ++} diff --git a/target/linux/brcm47xx/patches-3.10/081-MIPS-BCM47XX-Remove-CFE-support.patch b/target/linux/brcm47xx/patches-3.10/081-MIPS-BCM47XX-Remove-CFE-support.patch new file mode 100644 index 0000000000..1537db5158 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/081-MIPS-BCM47XX-Remove-CFE-support.patch @@ -0,0 +1,151 @@ +commit 808fe9c2fa81a6b3e20fe813d5410e7fd6606efa +Author: Hauke Mehrtens +Date: Sun Jul 18 15:11:26 2010 +0200 + + MIPS: BCM47XX: Remove CFE support + + bcm47xx only uses the CFE code for early print to a console, but that + is also possible with a early print serial 8250 driver. + + The CFE api init causes hangs somewhere in prom_init_cfe() on some + devices like the Buffalo WHR-HP-G54 and the Asus WL-520GU. + This was reported in https://dev.openwrt.org/ticket/4061 and + https://forum.openwrt.org/viewtopic.php?id=17063 + + This will remove all the CFE handling code from bcm47xx. + + Signed-off-by: Hauke Mehrtens + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -112,13 +112,11 @@ config BCM47XX + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT +- select FW_CFE + select HW_HAS_PCI + select IRQ_CPU + select NO_EXCEPT_FILL + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN +- select SYS_HAS_EARLY_PRINTK + help + Support for BCM47XX based boards + +--- a/arch/mips/bcm47xx/prom.c ++++ b/arch/mips/bcm47xx/prom.c +@@ -30,12 +30,9 @@ + #include + #include + #include +-#include +-#include + #include + #include + +-static int cfe_cons_handle; + + static char bcm47xx_system_type[20] = "Broadcom BCM47XX"; + +@@ -52,91 +49,6 @@ __init void bcm47xx_set_system_type(u16 + chip_id); + } + +-void prom_putchar(char c) +-{ +- while (cfe_write(cfe_cons_handle, &c, 1) == 0) +- ; +-} +- +-static __init void prom_init_cfe(void) +-{ +- uint32_t cfe_ept; +- uint32_t cfe_handle; +- uint32_t cfe_eptseal; +- int argc = fw_arg0; +- char **envp = (char **) fw_arg2; +- int *prom_vec = (int *) fw_arg3; +- +- /* +- * Check if a loader was used; if NOT, the 4 arguments are +- * what CFE gives us (handle, 0, EPT and EPTSEAL) +- */ +- if (argc < 0) { +- cfe_handle = (uint32_t)argc; +- cfe_ept = (uint32_t)envp; +- cfe_eptseal = (uint32_t)prom_vec; +- } else { +- if ((int)prom_vec < 0) { +- /* +- * Old loader; all it gives us is the handle, +- * so use the "known" entrypoint and assume +- * the seal. +- */ +- cfe_handle = (uint32_t)prom_vec; +- cfe_ept = 0xBFC00500; +- cfe_eptseal = CFE_EPTSEAL; +- } else { +- /* +- * Newer loaders bundle the handle/ept/eptseal +- * Note: prom_vec is in the loader's useg +- * which is still alive in the TLB. +- */ +- cfe_handle = prom_vec[0]; +- cfe_ept = prom_vec[2]; +- cfe_eptseal = prom_vec[3]; +- } +- } +- +- if (cfe_eptseal != CFE_EPTSEAL) { +- /* too early for panic to do any good */ +- printk(KERN_ERR "CFE's entrypoint seal doesn't match."); +- while (1) ; +- } +- +- cfe_init(cfe_handle, cfe_ept); +-} +- +-static __init void prom_init_console(void) +-{ +- /* Initialize CFE console */ +- cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); +-} +- +-static __init void prom_init_cmdline(void) +-{ +- static char buf[COMMAND_LINE_SIZE] __initdata; +- +- /* Get the kernel command line from CFE */ +- if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) { +- buf[COMMAND_LINE_SIZE - 1] = 0; +- strcpy(arcs_cmdline, buf); +- } +- +- /* Force a console handover by adding a console= argument if needed, +- * as CFE is not available anymore later in the boot process. */ +- if ((strstr(arcs_cmdline, "console=")) == NULL) { +- /* Try to read the default serial port used by CFE */ +- if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0) +- || (strncmp("uart", buf, 4))) +- /* Default to uart0 */ +- strcpy(buf, "uart0"); +- +- /* Compute the new command line */ +- snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200", +- arcs_cmdline, buf[4]); +- } +-} +- + static __init void prom_init_mem(void) + { + unsigned long mem; +@@ -184,9 +96,6 @@ static __init void prom_init_mem(void) + + void __init prom_init(void) + { +- prom_init_cfe(); +- prom_init_console(); +- prom_init_cmdline(); + prom_init_mem(); + } + diff --git a/target/linux/brcm47xx/patches-3.10/082-MIPS-BCM47XX-add-EARLY_PRINTK_8250-support.patch b/target/linux/brcm47xx/patches-3.10/082-MIPS-BCM47XX-add-EARLY_PRINTK_8250-support.patch new file mode 100644 index 0000000000..744e35985e --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/082-MIPS-BCM47XX-add-EARLY_PRINTK_8250-support.patch @@ -0,0 +1,53 @@ +commit 22250a38f970c173acb1b3fb30e6dce1430f697b +Author: Hauke Mehrtens +Date: Thu Sep 19 22:48:35 2013 +0200 + + MIPS: BCM47XX: add EARLY_PRINTK_8250 support + + The BCM47xx SoCs have a 8250 serial compatible console at address + 0x18000300 and an other at 0x18000400. On most devices 0x18000300 is + wired to some pins on the board, we should use that. + This is the smae for the AI (bcma) and the SB (ssb) bus, this is some + offset on the chip common core. + + Signed-off-by: Hauke Mehrtens + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -117,6 +117,8 @@ config BCM47XX + select NO_EXCEPT_FILL + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN ++ select SYS_HAS_EARLY_PRINTK ++ select EARLY_PRINTK_8250 if EARLY_PRINTK + help + Support for BCM47XX based boards + +--- a/arch/mips/bcm47xx/prom.c ++++ b/arch/mips/bcm47xx/prom.c +@@ -28,6 +28,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -94,9 +96,16 @@ static __init void prom_init_mem(void) + add_memory_region(0, mem, BOOT_MEM_RAM); + } + ++/* ++ * This is the first serial on the chip common core, it is at this position ++ * for sb (ssb) and ai (bcma) bus. ++ */ ++#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA) ++ + void __init prom_init(void) + { + prom_init_mem(); ++ setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0); + } + + void __init prom_free_prom_memory(void) diff --git a/target/linux/brcm47xx/patches-3.10/114-MIPS-BCM47xx-Setup-and-register-serial-early.patch b/target/linux/brcm47xx/patches-3.10/114-MIPS-BCM47xx-Setup-and-register-serial-early.patch deleted file mode 100644 index 3972458a95..0000000000 --- a/target/linux/brcm47xx/patches-3.10/114-MIPS-BCM47xx-Setup-and-register-serial-early.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9be402f069cc259ad5795b77567d66c4e7f6bef6 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 18 Jul 2010 14:59:24 +0200 -Subject: [PATCH 4/6] MIPS: BCM47xx: Setup and register serial early - -Swap the first and second serial if console=ttyS1 was set. -Set it up and register it for early serial support. - -This patch has been in OpenWRT for a long time. - -Signed-off-by: Hauke Mehrtens ---- - arch/mips/bcm47xx/setup.c | 39 ++++++++++++++++++++++++++++++++++++++- - 1 files changed, 38 insertions(+), 1 deletions(-) - ---- a/arch/mips/bcm47xx/setup.c -+++ b/arch/mips/bcm47xx/setup.c -@@ -31,6 +31,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -123,6 +125,31 @@ static int bcm47xx_get_invariants(struct - return 0; - } - -+#ifdef CONFIG_SERIAL_8250 -+static void __init bcm47xx_early_serial_setup(struct ssb_mipscore *mcore) -+{ -+ int i; -+ -+ for (i = 0; i < mcore->nr_serial_ports; i++) { -+ struct ssb_serial_port *port = &(mcore->serial_ports[i]); -+ struct uart_port s; -+ -+ memset(&s, 0, sizeof(s)); -+ s.line = i; -+ s.mapbase = (unsigned int) port->regs; -+ s.membase = port->regs; -+ s.irq = port->irq + 2; -+ s.uartclk = port->baud_base; -+ s.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; -+ s.iotype = SERIAL_IO_MEM; -+ s.regshift = port->reg_shift; -+ -+ early_serial_setup(&s); -+ } -+ printk(KERN_DEBUG "Serial init done.\n"); -+} -+#endif -+ - static void __init bcm47xx_register_ssb(void) - { - int err; -@@ -152,6 +179,10 @@ static void __init bcm47xx_register_ssb( - memcpy(&mcore->serial_ports[1], &port, sizeof(port)); - } - } -+ -+#ifdef CONFIG_SERIAL_8250 -+ bcm47xx_early_serial_setup(mcore); -+#endif - } - #endif - diff --git a/target/linux/brcm47xx/patches-3.10/116-MIPS-BCM47xx-Remove-CFE-console.patch b/target/linux/brcm47xx/patches-3.10/116-MIPS-BCM47xx-Remove-CFE-console.patch deleted file mode 100644 index ecccd82566..0000000000 --- a/target/linux/brcm47xx/patches-3.10/116-MIPS-BCM47xx-Remove-CFE-console.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 5219981646071abb6731634bf47781a53e248764 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 18 Jul 2010 15:11:26 +0200 -Subject: [PATCH 6/6] MIPS: BCM47xx: Remove CFE console - -Do not use the CFE console. It causes hangs on some devices like the -Buffalo WHR-HP-G54. -This was reported in https://dev.openwrt.org/ticket/4061 and -https://forum.openwrt.org/viewtopic.php?id=17063 - -Signed-off-by: Hauke Mehrtens ---- - arch/mips/Kconfig | 1 - - arch/mips/bcm47xx/prom.c | 82 +++------------------------------------------ - 2 files changed, 6 insertions(+), 77 deletions(-) - ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -118,7 +118,6 @@ config BCM47XX - select NO_EXCEPT_FILL - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN -- select SYS_HAS_EARLY_PRINTK - help - Support for BCM47XX based boards - ---- a/arch/mips/bcm47xx/prom.c -+++ b/arch/mips/bcm47xx/prom.c -@@ -35,8 +35,6 @@ - #include - #include - --static int cfe_cons_handle; -- - static char bcm47xx_system_type[20] = "Broadcom BCM47XX"; - - const char *get_system_type(void) -@@ -52,89 +50,23 @@ __init void bcm47xx_set_system_type(u16 - chip_id); - } - --void prom_putchar(char c) --{ -- while (cfe_write(cfe_cons_handle, &c, 1) == 0) -- ; --} -- --static __init void prom_init_cfe(void) -+static __init int prom_init_cfe(void) - { - uint32_t cfe_ept; - uint32_t cfe_handle; - uint32_t cfe_eptseal; -- int argc = fw_arg0; -- char **envp = (char **) fw_arg2; -- int *prom_vec = (int *) fw_arg3; -- -- /* -- * Check if a loader was used; if NOT, the 4 arguments are -- * what CFE gives us (handle, 0, EPT and EPTSEAL) -- */ -- if (argc < 0) { -- cfe_handle = (uint32_t)argc; -- cfe_ept = (uint32_t)envp; -- cfe_eptseal = (uint32_t)prom_vec; -- } else { -- if ((int)prom_vec < 0) { -- /* -- * Old loader; all it gives us is the handle, -- * so use the "known" entrypoint and assume -- * the seal. -- */ -- cfe_handle = (uint32_t)prom_vec; -- cfe_ept = 0xBFC00500; -- cfe_eptseal = CFE_EPTSEAL; -- } else { -- /* -- * Newer loaders bundle the handle/ept/eptseal -- * Note: prom_vec is in the loader's useg -- * which is still alive in the TLB. -- */ -- cfe_handle = prom_vec[0]; -- cfe_ept = prom_vec[2]; -- cfe_eptseal = prom_vec[3]; -- } -- } -+ -+ cfe_eptseal = (uint32_t) fw_arg3; -+ cfe_handle = (uint32_t) fw_arg0; -+ cfe_ept = (uint32_t) fw_arg2; - - if (cfe_eptseal != CFE_EPTSEAL) { -- /* too early for panic to do any good */ - printk(KERN_ERR "CFE's entrypoint seal doesn't match."); -- while (1) ; -+ return -1; - } - - cfe_init(cfe_handle, cfe_ept); --} -- --static __init void prom_init_console(void) --{ -- /* Initialize CFE console */ -- cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); --} -- --static __init void prom_init_cmdline(void) --{ -- static char buf[COMMAND_LINE_SIZE] __initdata; -- -- /* Get the kernel command line from CFE */ -- if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) { -- buf[COMMAND_LINE_SIZE - 1] = 0; -- strcpy(arcs_cmdline, buf); -- } -- -- /* Force a console handover by adding a console= argument if needed, -- * as CFE is not available anymore later in the boot process. */ -- if ((strstr(arcs_cmdline, "console=")) == NULL) { -- /* Try to read the default serial port used by CFE */ -- if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0) -- || (strncmp("uart", buf, 4))) -- /* Default to uart0 */ -- strcpy(buf, "uart0"); -- -- /* Compute the new command line */ -- snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200", -- arcs_cmdline, buf[4]); -- } -+ return 0; - } - - static __init void prom_init_mem(void) -@@ -185,8 +117,6 @@ static __init void prom_init_mem(void) - void __init prom_init(void) - { - prom_init_cfe(); -- prom_init_console(); -- prom_init_cmdline(); - prom_init_mem(); - } - diff --git a/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch b/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch index 5e8a2cb461..333b9e6c5b 100644 --- a/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch +++ b/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch @@ -1,14 +1,14 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -33,6 +33,7 @@ +@@ -31,6 +31,7 @@ + #include + #include #include - #include - #include +#include #include #include #include -@@ -260,6 +261,33 @@ void __init plat_mem_setup(void) +@@ -229,6 +230,33 @@ void __init plat_mem_setup(void) mips_set_machine_name(bcm47xx_board_get_name()); } @@ -42,7 +42,7 @@ static int __init bcm47xx_register_bus_complete(void) { switch (bcm47xx_bus_type) { -@@ -274,6 +302,8 @@ static int __init bcm47xx_register_bus_c +@@ -243,6 +271,8 @@ static int __init bcm47xx_register_bus_c break; #endif } diff --git a/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch b/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch index 55c7365fef..069a0fa7a2 100644 --- a/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch +++ b/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch @@ -1,6 +1,6 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -123,6 +123,10 @@ static int bcm47xx_get_invariants(struct +@@ -121,6 +121,10 @@ static int bcm47xx_get_invariants(struct if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);