From 3bdf05441aa8e7df8e41793eff8a9bbd50c5f153 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Jan 2015 12:48:27 +0000 Subject: [PATCH] brcm47xx: backport BCM47XX arch patches (clean NVRAM code, later init) SVN-Revision: 43979 --- ...CM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch | 132 +++++++++++ ...e-ssb-init-NVRAM-instead-of-bcm47xx-.patch | 133 +++++++++++ ...e-bcma-init-NVRAM-instead-of-bcm47xx.patch | 113 +++++++++ ...ove-SPROM-fallback-code-into-sprom.c.patch | 216 ++++++++++++++++++ ...tialize-bcma-bus-later-with-mm-avail.patch | 120 ++++++++++ .../patches-3.14/820-wgt634u-nvram-fix.patch | 12 +- .../830-huawei_e970_support.patch | 4 +- .../980-wnr834b_no_cardbus_invariant.patch | 2 +- ...CM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch | 132 +++++++++++ ...e-ssb-init-NVRAM-instead-of-bcm47xx-.patch | 133 +++++++++++ ...e-bcma-init-NVRAM-instead-of-bcm47xx.patch | 113 +++++++++ ...ove-SPROM-fallback-code-into-sprom.c.patch | 216 ++++++++++++++++++ ...tialize-bcma-bus-later-with-mm-avail.patch | 120 ++++++++++ .../patches-3.18/820-wgt634u-nvram-fix.patch | 12 +- .../830-huawei_e970_support.patch | 4 +- .../980-wnr834b_no_cardbus_invariant.patch | 2 +- 16 files changed, 1446 insertions(+), 18 deletions(-) create mode 100644 target/linux/brcm47xx/patches-3.14/154-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch create mode 100644 target/linux/brcm47xx/patches-3.14/155-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch create mode 100644 target/linux/brcm47xx/patches-3.14/156-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch create mode 100644 target/linux/brcm47xx/patches-3.14/157-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch create mode 100644 target/linux/brcm47xx/patches-3.14/158-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch create mode 100644 target/linux/brcm47xx/patches-3.18/030-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch create mode 100644 target/linux/brcm47xx/patches-3.18/031-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch create mode 100644 target/linux/brcm47xx/patches-3.18/032-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch create mode 100644 target/linux/brcm47xx/patches-3.18/033-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch create mode 100644 target/linux/brcm47xx/patches-3.18/034-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch diff --git a/target/linux/brcm47xx/patches-3.14/154-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch b/target/linux/brcm47xx/patches-3.14/154-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch new file mode 100644 index 0000000000..4b2f6a27e2 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/154-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch @@ -0,0 +1,132 @@ +From 8d602dd0f984e8488ab891344ebdb6e1f3128c4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 3 Sep 2014 22:51:06 +0200 +Subject: [PATCH 154/158] MIPS: BCM47XX: Get rid of calls to KSEG1ADDR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We should be using ioremap_nocache helper which handles remaps in a +smarter way. + +Signed-off-by: Rafał Miłecki +Cc: linux-mips@linux-mips.org +Cc: Hauke Mehrtens +Patchwork: http://patchwork.linux-mips.org/patch/7611/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 44 ++++++++++++++++++++++++++++++++------------ + 1 file changed, 32 insertions(+), 12 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index 2bed73a..e07976b 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -23,13 +23,13 @@ + static char nvram_buf[NVRAM_SPACE]; + static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; + +-static u32 find_nvram_size(u32 end) ++static u32 find_nvram_size(void __iomem *end) + { +- struct nvram_header *header; ++ struct nvram_header __iomem *header; + int i; + + for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { +- header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); ++ header = (struct nvram_header *)(end - nvram_sizes[i]); + if (header->magic == NVRAM_HEADER) + return nvram_sizes[i]; + } +@@ -38,35 +38,39 @@ static u32 find_nvram_size(u32 end) + } + + /* Probe for NVRAM header */ +-static int nvram_find_and_copy(u32 base, u32 lim) ++static int nvram_find_and_copy(void __iomem *iobase, u32 lim) + { +- struct nvram_header *header; ++ struct nvram_header __iomem *header; + int i; + u32 off; + u32 *src, *dst; + u32 size; + ++ if (nvram_buf[0]) { ++ pr_warn("nvram already initialized\n"); ++ return -EEXIST; ++ } ++ + /* TODO: when nvram is on nand flash check for bad blocks first. */ + off = FLASH_MIN; + while (off <= lim) { + /* Windowed flash access */ +- size = find_nvram_size(base + off); ++ size = find_nvram_size(iobase + off); + if (size) { +- header = (struct nvram_header *)KSEG1ADDR(base + off - +- size); ++ header = (struct nvram_header *)(iobase + off - size); + goto found; + } + off <<= 1; + } + + /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ +- header = (struct nvram_header *) KSEG1ADDR(base + 4096); ++ header = (struct nvram_header *)(iobase + 4096); + if (header->magic == NVRAM_HEADER) { + size = NVRAM_SPACE; + goto found; + } + +- header = (struct nvram_header *) KSEG1ADDR(base + 1024); ++ header = (struct nvram_header *)(iobase + 1024); + if (header->magic == NVRAM_HEADER) { + size = NVRAM_SPACE; + goto found; +@@ -94,6 +98,22 @@ found: + return 0; + } + ++static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) ++{ ++ void __iomem *iobase; ++ int err; ++ ++ iobase = ioremap_nocache(base, lim); ++ if (!iobase) ++ return -ENOMEM; ++ ++ err = nvram_find_and_copy(iobase, lim); ++ ++ iounmap(iobase); ++ ++ return err; ++} ++ + #ifdef CONFIG_BCM47XX_SSB + static int nvram_init_ssb(void) + { +@@ -109,7 +129,7 @@ static int nvram_init_ssb(void) + return -ENXIO; + } + +- return nvram_find_and_copy(base, lim); ++ return bcm47xx_nvram_init_from_mem(base, lim); + } + #endif + +@@ -139,7 +159,7 @@ static int nvram_init_bcma(void) + return -ENXIO; + } + +- return nvram_find_and_copy(base, lim); ++ return bcm47xx_nvram_init_from_mem(base, lim); + } + #endif + +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.14/155-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch b/target/linux/brcm47xx/patches-3.14/155-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch new file mode 100644 index 0000000000..07a782da8f --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/155-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch @@ -0,0 +1,133 @@ +From 21400f252a97755579b43a4dc95dd02cd7f0ca75 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 3 Sep 2014 22:59:45 +0200 +Subject: [PATCH 155/158] MIPS: BCM47XX: Make ssb init NVRAM instead of bcm47xx + polling it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This makes NVRAM code less bcm47xx/ssb specific allowing it to become a +standalone driver in the future. A similar patch for bcma will follow +when it's ready. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/7612/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 30 +++++++--------------- + arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | 1 + + drivers/ssb/driver_mipscore.c | 14 +++++++++- + 3 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index e07976b..fecc5ae 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -98,7 +98,14 @@ found: + return 0; + } + +-static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) ++/* ++ * On bcm47xx we need access to the NVRAM very early, so we can't use mtd ++ * subsystem to access flash. We can't even use platform device / driver to ++ * store memory offset. ++ * To handle this we provide following symbol. It's supposed to be called as ++ * soon as we get info about flash device, before any NVRAM entry is needed. ++ */ ++int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + { + void __iomem *iobase; + int err; +@@ -114,25 +121,6 @@ static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + return err; + } + +-#ifdef CONFIG_BCM47XX_SSB +-static int nvram_init_ssb(void) +-{ +- struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; +- u32 base; +- u32 lim; +- +- if (mcore->pflash.present) { +- base = mcore->pflash.window; +- lim = mcore->pflash.window_size; +- } else { +- pr_err("Couldn't find supported flash memory\n"); +- return -ENXIO; +- } +- +- return bcm47xx_nvram_init_from_mem(base, lim); +-} +-#endif +- + #ifdef CONFIG_BCM47XX_BCMA + static int nvram_init_bcma(void) + { +@@ -168,7 +156,7 @@ static int nvram_init(void) + switch (bcm47xx_bus_type) { + #ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: +- return nvram_init_ssb(); ++ break; + #endif + #ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: +diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +index 36a3fc1..676be22 100644 +--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h ++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +@@ -32,6 +32,7 @@ struct nvram_header { + #define NVRAM_MAX_VALUE_LEN 255 + #define NVRAM_MAX_PARAM_LEN 64 + ++int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); + extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); + + static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) +diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c +index 0907706..7b986f9 100644 +--- a/drivers/ssb/driver_mipscore.c ++++ b/drivers/ssb/driver_mipscore.c +@@ -15,6 +15,9 @@ + #include + #include + #include ++#ifdef CONFIG_BCM47XX ++#include ++#endif + + #include "ssb_private.h" + +@@ -210,6 +213,7 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore) + static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) + { + struct ssb_bus *bus = mcore->dev->bus; ++ struct ssb_sflash *sflash = &mcore->sflash; + struct ssb_pflash *pflash = &mcore->pflash; + + /* When there is no chipcommon on the bus there is 4MB flash */ +@@ -242,7 +246,15 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) + } + + ssb_pflash: +- if (pflash->present) { ++ if (sflash->present) { ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(sflash->window, sflash->size); ++#endif ++ } else if (pflash->present) { ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size); ++#endif ++ + ssb_pflash_data.width = pflash->buswidth; + ssb_pflash_resource.start = pflash->window; + ssb_pflash_resource.end = pflash->window + pflash->window_size; +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.14/156-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch b/target/linux/brcm47xx/patches-3.14/156-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch new file mode 100644 index 0000000000..a616fcc0e0 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/156-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch @@ -0,0 +1,113 @@ +From 7177efc5b030012c54c2e217c9d6decc0bcc1c53 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 13:30:23 +0100 +Subject: [PATCH 156/158] MIPS: BCM47XX: Make bcma init NVRAM instead of + bcm47xx polling it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This drops ssb/bcma dependency and will allow us to make it a standalone +driver. + +Signed-off-by: Rafał Miłecki +Cc: linux-mips@linux-mips.org +Cc: Hauke Mehrtens +Patchwork: https://patchwork.linux-mips.org/patch/8233/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 42 ++---------------------------------------- + drivers/bcma/driver_mips.c | 13 +++++++++++-- + 2 files changed, 13 insertions(+), 42 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index fecc5ae..21712fb 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -121,48 +121,10 @@ int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + return err; + } + +-#ifdef CONFIG_BCM47XX_BCMA +-static int nvram_init_bcma(void) +-{ +- struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; +- u32 base; +- u32 lim; +- +-#ifdef CONFIG_BCMA_NFLASH +- if (cc->nflash.boot) { +- base = BCMA_SOC_FLASH1; +- lim = BCMA_SOC_FLASH1_SZ; +- } else +-#endif +- if (cc->pflash.present) { +- base = cc->pflash.window; +- lim = cc->pflash.window_size; +-#ifdef CONFIG_BCMA_SFLASH +- } else if (cc->sflash.present) { +- base = cc->sflash.window; +- lim = cc->sflash.size; +-#endif +- } else { +- pr_err("Couldn't find supported flash memory\n"); +- return -ENXIO; +- } +- +- return bcm47xx_nvram_init_from_mem(base, lim); +-} +-#endif +- + static int nvram_init(void) + { +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- break; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- return nvram_init_bcma(); +-#endif +- } ++ /* TODO: Look for MTD "nvram" partition */ ++ + return -ENXIO; + } + +diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c +index 004d6aa..8a653dc 100644 +--- a/drivers/bcma/driver_mips.c ++++ b/drivers/bcma/driver_mips.c +@@ -20,6 +20,9 @@ + #include + #include + #include ++#ifdef CONFIG_BCM47XX ++#include ++#endif + + enum bcma_boot_dev { + BCMA_BOOT_DEV_UNK = 0, +@@ -316,10 +319,16 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) + switch (boot_dev) { + case BCMA_BOOT_DEV_PARALLEL: + case BCMA_BOOT_DEV_SERIAL: +- /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */ ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2, ++ BCMA_SOC_FLASH2_SZ); ++#endif + break; + case BCMA_BOOT_DEV_NAND: +- /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */ ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1, ++ BCMA_SOC_FLASH1_SZ); ++#endif + break; + default: + break; +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.14/157-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch b/target/linux/brcm47xx/patches-3.14/157-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch new file mode 100644 index 0000000000..fe4962993b --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/157-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch @@ -0,0 +1,216 @@ +From a59da8fb3b2a1f2df5f871464e43cd5b6ca6ceb1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 12:52:02 +0100 +Subject: [PATCH 157/158] MIPS: BCM47XX: Move SPROM fallback code into sprom.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is some general cleanup as well as preparing sprom.c to become a +standalone driver. We will need this for bcm53xx ARM arch support. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/8232/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/bcm47xx_private.h | 3 ++ + arch/mips/bcm47xx/setup.c | 58 ++----------------------------- + arch/mips/bcm47xx/sprom.c | 68 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 73 insertions(+), 56 deletions(-) + +diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h +index f1cc9d0..12a112d 100644 +--- a/arch/mips/bcm47xx/bcm47xx_private.h ++++ b/arch/mips/bcm47xx/bcm47xx_private.h +@@ -6,6 +6,9 @@ + /* prom.c */ + void __init bcm47xx_prom_highmem_init(void); + ++/* sprom.c */ ++void bcm47xx_sprom_register_fallbacks(void); ++ + /* buttons.c */ + int __init bcm47xx_buttons_register(void); + +diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c +index c00585d..444c65a 100644 +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) + } + + #ifdef CONFIG_BCM47XX_SSB +-static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) +-{ +- char prefix[10]; +- +- if (bus->bustype == SSB_BUSTYPE_PCI) { +- memset(out, 0, sizeof(struct ssb_sprom)); +- snprintf(prefix, sizeof(prefix), "pci/%u/%u/", +- bus->host_pci->bus->number + 1, +- PCI_SLOT(bus->host_pci->devfn)); +- bcm47xx_fill_sprom(out, prefix, false); +- return 0; +- } else { +- printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); +- return -EINVAL; +- } +-} +- + static int bcm47xx_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv) + { +@@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) + char buf[100]; + struct ssb_mipscore *mcore; + +- err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); +- if (err) +- printk(KERN_WARNING "bcm47xx: someone else already registered" +- " a ssb SPROM callback handler (err %d)\n", err); +- + err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, + bcm47xx_get_invariants); + if (err) +@@ -171,44 +149,10 @@ static void __init bcm47xx_register_ssb(void) + #endif + + #ifdef CONFIG_BCM47XX_BCMA +-static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) +-{ +- char prefix[10]; +- struct bcma_device *core; +- +- switch (bus->hosttype) { +- case BCMA_HOSTTYPE_PCI: +- memset(out, 0, sizeof(struct ssb_sprom)); +- snprintf(prefix, sizeof(prefix), "pci/%u/%u/", +- bus->host_pci->bus->number + 1, +- PCI_SLOT(bus->host_pci->devfn)); +- bcm47xx_fill_sprom(out, prefix, false); +- return 0; +- case BCMA_HOSTTYPE_SOC: +- memset(out, 0, sizeof(struct ssb_sprom)); +- core = bcma_find_core(bus, BCMA_CORE_80211); +- if (core) { +- snprintf(prefix, sizeof(prefix), "sb/%u/", +- core->core_index); +- bcm47xx_fill_sprom(out, prefix, true); +- } else { +- bcm47xx_fill_sprom(out, NULL, false); +- } +- return 0; +- default: +- pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); +- return -EINVAL; +- } +-} +- + static void __init bcm47xx_register_bcma(void) + { + int err; + +- err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); +- if (err) +- pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); +- + err = bcma_host_soc_register(&bcm47xx_bus.bcma); + if (err) + panic("Failed to register BCMA bus (err %d)", err); +@@ -229,6 +173,7 @@ void __init plat_mem_setup(void) + printk(KERN_INFO "bcm47xx: using bcma bus\n"); + #ifdef CONFIG_BCM47XX_BCMA + bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; ++ bcm47xx_sprom_register_fallbacks(); + bcm47xx_register_bcma(); + bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); + #ifdef CONFIG_HIGHMEM +@@ -239,6 +184,7 @@ void __init plat_mem_setup(void) + printk(KERN_INFO "bcm47xx: using ssb bus\n"); + #ifdef CONFIG_BCM47XX_SSB + bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; ++ bcm47xx_sprom_register_fallbacks(); + bcm47xx_register_ssb(); + bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); + #endif +diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c +index 41226b6..e772e77 100644 +--- a/arch/mips/bcm47xx/sprom.c ++++ b/arch/mips/bcm47xx/sprom.c +@@ -801,3 +801,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); + } + #endif ++ ++#if defined(CONFIG_BCM47XX_SSB) ++static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) ++{ ++ char prefix[10]; ++ ++ if (bus->bustype == SSB_BUSTYPE_PCI) { ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ snprintf(prefix, sizeof(prefix), "pci/%u/%u/", ++ bus->host_pci->bus->number + 1, ++ PCI_SLOT(bus->host_pci->devfn)); ++ bcm47xx_fill_sprom(out, prefix, false); ++ return 0; ++ } else { ++ pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); ++ return -EINVAL; ++ } ++} ++#endif ++ ++#if defined(CONFIG_BCM47XX_BCMA) ++static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) ++{ ++ char prefix[10]; ++ struct bcma_device *core; ++ ++ switch (bus->hosttype) { ++ case BCMA_HOSTTYPE_PCI: ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ snprintf(prefix, sizeof(prefix), "pci/%u/%u/", ++ bus->host_pci->bus->number + 1, ++ PCI_SLOT(bus->host_pci->devfn)); ++ bcm47xx_fill_sprom(out, prefix, false); ++ return 0; ++ case BCMA_HOSTTYPE_SOC: ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ core = bcma_find_core(bus, BCMA_CORE_80211); ++ if (core) { ++ snprintf(prefix, sizeof(prefix), "sb/%u/", ++ core->core_index); ++ bcm47xx_fill_sprom(out, prefix, true); ++ } else { ++ bcm47xx_fill_sprom(out, NULL, false); ++ } ++ return 0; ++ default: ++ pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); ++ return -EINVAL; ++ } ++} ++#endif ++ ++/* ++ * On bcm47xx we need to register SPROM fallback handler very early, so we can't ++ * use anything like platform device / driver for this. ++ */ ++void bcm47xx_sprom_register_fallbacks(void) ++{ ++#if defined(CONFIG_BCM47XX_SSB) ++ if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) ++ pr_warn("Failed to registered ssb SPROM handler\n"); ++#endif ++ ++#if defined(CONFIG_BCM47XX_BCMA) ++ if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) ++ pr_warn("Failed to registered bcma SPROM handler\n"); ++#endif ++} +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.14/158-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch b/target/linux/brcm47xx/patches-3.14/158-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch new file mode 100644 index 0000000000..54680de0b7 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.14/158-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch @@ -0,0 +1,120 @@ +From e5810fa0c1bed16fdfb408862a2e17e962ec5cf6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 14:40:38 +0100 +Subject: [PATCH 158/158] MIPS: BCM47XX: Initialize bcma bus later (with mm + available) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Initializaion with memory allocator available will be much simpler, this +will allow cleanup in the bcma code. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/8234/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/bcm47xx_private.h | 3 +++ + arch/mips/bcm47xx/irq.c | 8 ++++++++ + arch/mips/bcm47xx/setup.c | 33 +++++++++++++++++++++++++++------ + 3 files changed, 38 insertions(+), 6 deletions(-) + +diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h +index 12a112d..ea909a5 100644 +--- a/arch/mips/bcm47xx/bcm47xx_private.h ++++ b/arch/mips/bcm47xx/bcm47xx_private.h +@@ -15,6 +15,9 @@ int __init bcm47xx_buttons_register(void); + /* leds.c */ + void __init bcm47xx_leds_register(void); + ++/* setup.c */ ++void __init bcm47xx_bus_setup(void); ++ + /* workarounds.c */ + void __init bcm47xx_workarounds(void); + +diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c +index e0585b7..21b4497 100644 +--- a/arch/mips/bcm47xx/irq.c ++++ b/arch/mips/bcm47xx/irq.c +@@ -22,6 +22,8 @@ + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include "bcm47xx_private.h" ++ + #include + #include + #include +@@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) + + void __init arch_init_irq(void) + { ++ /* ++ * This is the first arch callback after mm_init (we can use kmalloc), ++ * so let's finish bus initialization now. ++ */ ++ bcm47xx_bus_setup(); ++ + #ifdef CONFIG_BCM47XX_BCMA + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { + bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, +diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c +index 444c65a..e43b504 100644 +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -156,15 +156,14 @@ static void __init bcm47xx_register_bcma(void) + err = bcma_host_soc_register(&bcm47xx_bus.bcma); + if (err) + panic("Failed to register BCMA bus (err %d)", err); +- +- err = bcma_host_soc_init(&bcm47xx_bus.bcma); +- if (err) +- panic("Failed to initialize BCMA bus (err %d)", err); +- +- bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); + } + #endif + ++/* ++ * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed ++ * to detect memory and record it with add_memory_region. ++ * Any extra initializaion performed here must not use kmalloc or bootmem. ++ */ + void __init plat_mem_setup(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; +@@ -193,6 +192,28 @@ void __init plat_mem_setup(void) + _machine_restart = bcm47xx_machine_restart; + _machine_halt = bcm47xx_machine_halt; + pm_power_off = bcm47xx_machine_halt; ++} ++ ++/* ++ * This finishes bus initialization doing things that were not possible without ++ * kmalloc. Make sure to call it late enough (after mm_init). ++ */ ++void __init bcm47xx_bus_setup(void) ++{ ++#ifdef CONFIG_BCM47XX_BCMA ++ if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { ++ int err; ++ ++ err = bcma_host_soc_init(&bcm47xx_bus.bcma); ++ if (err) ++ panic("Failed to initialize BCMA bus (err %d)", err); ++ ++ bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, ++ NULL); ++ } ++#endif ++ ++ /* With bus initialized we can access NVRAM and detect the board */ + bcm47xx_board_detect(); + mips_set_machine_name(bcm47xx_board_get_name()); + } +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.14/820-wgt634u-nvram-fix.patch b/target/linux/brcm47xx/patches-3.14/820-wgt634u-nvram-fix.patch index e2bbdcc15f..ea002fe732 100644 --- a/target/linux/brcm47xx/patches-3.14/820-wgt634u-nvram-fix.patch +++ b/target/linux/brcm47xx/patches-3.14/820-wgt634u-nvram-fix.patch @@ -251,17 +251,17 @@ out the configuration than the in kernel cfe config reader. +static int cfe_env; +extern char *cfe_env_get(char *nv_buf, const char *name); - static u32 find_nvram_size(u32 end) + static u32 find_nvram_size(void __iomem *end) { -@@ -46,6 +48,26 @@ static int nvram_find_and_copy(u32 base, - u32 *src, *dst; - u32 size; +@@ -51,6 +53,26 @@ static int nvram_find_and_copy(void __io + return -EEXIST; + } + cfe_env = 0; + + /* XXX: hack for supporting the CFE environment stuff on WGT634U */ + if (lim >= 8 * 1024 * 1024) { -+ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ src = (u32 *) iobase + 8 * 1024 * 1024 - 0x2000; + dst = (u32 *) nvram_buf; + + if ((*src & 0xff00ff) == 0x000001) { @@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader. /* TODO: when nvram is on nand flash check for bad blocks first. */ off = FLASH_MIN; while (off <= lim) { -@@ -172,6 +194,13 @@ int bcm47xx_nvram_getenv(char *name, cha +@@ -142,6 +164,13 @@ int bcm47xx_nvram_getenv(char *name, cha return err; } diff --git a/target/linux/brcm47xx/patches-3.14/830-huawei_e970_support.patch b/target/linux/brcm47xx/patches-3.14/830-huawei_e970_support.patch index 5425d049cb..bab051a647 100644 --- a/target/linux/brcm47xx/patches-3.14/830-huawei_e970_support.patch +++ b/target/linux/brcm47xx/patches-3.14/830-huawei_e970_support.patch @@ -8,7 +8,7 @@ #include #include #include -@@ -282,6 +283,33 @@ static struct fixed_phy_status bcm47xx_f +@@ -249,6 +250,33 @@ static struct fixed_phy_status bcm47xx_f .duplex = DUPLEX_FULL, }; @@ -42,7 +42,7 @@ static int __init bcm47xx_register_bus_complete(void) { switch (bcm47xx_bus_type) { -@@ -301,6 +329,7 @@ static int __init bcm47xx_register_bus_c +@@ -268,6 +296,7 @@ static int __init bcm47xx_register_bus_c bcm47xx_workarounds(); fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); diff --git a/target/linux/brcm47xx/patches-3.14/980-wnr834b_no_cardbus_invariant.patch b/target/linux/brcm47xx/patches-3.14/980-wnr834b_no_cardbus_invariant.patch index 8bab5f09bf..86c00c93a3 100644 --- a/target/linux/brcm47xx/patches-3.14/980-wnr834b_no_cardbus_invariant.patch +++ b/target/linux/brcm47xx/patches-3.14/980-wnr834b_no_cardbus_invariant.patch @@ -1,6 +1,6 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -136,6 +136,10 @@ static int bcm47xx_get_invariants(struct +@@ -119,6 +119,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); diff --git a/target/linux/brcm47xx/patches-3.18/030-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch b/target/linux/brcm47xx/patches-3.18/030-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch new file mode 100644 index 0000000000..4b2f6a27e2 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.18/030-MIPS-BCM47XX-Get-rid-of-calls-to-KSEG1ADDR.patch @@ -0,0 +1,132 @@ +From 8d602dd0f984e8488ab891344ebdb6e1f3128c4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 3 Sep 2014 22:51:06 +0200 +Subject: [PATCH 154/158] MIPS: BCM47XX: Get rid of calls to KSEG1ADDR +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We should be using ioremap_nocache helper which handles remaps in a +smarter way. + +Signed-off-by: Rafał Miłecki +Cc: linux-mips@linux-mips.org +Cc: Hauke Mehrtens +Patchwork: http://patchwork.linux-mips.org/patch/7611/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 44 ++++++++++++++++++++++++++++++++------------ + 1 file changed, 32 insertions(+), 12 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index 2bed73a..e07976b 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -23,13 +23,13 @@ + static char nvram_buf[NVRAM_SPACE]; + static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; + +-static u32 find_nvram_size(u32 end) ++static u32 find_nvram_size(void __iomem *end) + { +- struct nvram_header *header; ++ struct nvram_header __iomem *header; + int i; + + for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { +- header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); ++ header = (struct nvram_header *)(end - nvram_sizes[i]); + if (header->magic == NVRAM_HEADER) + return nvram_sizes[i]; + } +@@ -38,35 +38,39 @@ static u32 find_nvram_size(u32 end) + } + + /* Probe for NVRAM header */ +-static int nvram_find_and_copy(u32 base, u32 lim) ++static int nvram_find_and_copy(void __iomem *iobase, u32 lim) + { +- struct nvram_header *header; ++ struct nvram_header __iomem *header; + int i; + u32 off; + u32 *src, *dst; + u32 size; + ++ if (nvram_buf[0]) { ++ pr_warn("nvram already initialized\n"); ++ return -EEXIST; ++ } ++ + /* TODO: when nvram is on nand flash check for bad blocks first. */ + off = FLASH_MIN; + while (off <= lim) { + /* Windowed flash access */ +- size = find_nvram_size(base + off); ++ size = find_nvram_size(iobase + off); + if (size) { +- header = (struct nvram_header *)KSEG1ADDR(base + off - +- size); ++ header = (struct nvram_header *)(iobase + off - size); + goto found; + } + off <<= 1; + } + + /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ +- header = (struct nvram_header *) KSEG1ADDR(base + 4096); ++ header = (struct nvram_header *)(iobase + 4096); + if (header->magic == NVRAM_HEADER) { + size = NVRAM_SPACE; + goto found; + } + +- header = (struct nvram_header *) KSEG1ADDR(base + 1024); ++ header = (struct nvram_header *)(iobase + 1024); + if (header->magic == NVRAM_HEADER) { + size = NVRAM_SPACE; + goto found; +@@ -94,6 +98,22 @@ found: + return 0; + } + ++static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) ++{ ++ void __iomem *iobase; ++ int err; ++ ++ iobase = ioremap_nocache(base, lim); ++ if (!iobase) ++ return -ENOMEM; ++ ++ err = nvram_find_and_copy(iobase, lim); ++ ++ iounmap(iobase); ++ ++ return err; ++} ++ + #ifdef CONFIG_BCM47XX_SSB + static int nvram_init_ssb(void) + { +@@ -109,7 +129,7 @@ static int nvram_init_ssb(void) + return -ENXIO; + } + +- return nvram_find_and_copy(base, lim); ++ return bcm47xx_nvram_init_from_mem(base, lim); + } + #endif + +@@ -139,7 +159,7 @@ static int nvram_init_bcma(void) + return -ENXIO; + } + +- return nvram_find_and_copy(base, lim); ++ return bcm47xx_nvram_init_from_mem(base, lim); + } + #endif + +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.18/031-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch b/target/linux/brcm47xx/patches-3.18/031-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch new file mode 100644 index 0000000000..07a782da8f --- /dev/null +++ b/target/linux/brcm47xx/patches-3.18/031-MIPS-BCM47XX-Make-ssb-init-NVRAM-instead-of-bcm47xx-.patch @@ -0,0 +1,133 @@ +From 21400f252a97755579b43a4dc95dd02cd7f0ca75 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 3 Sep 2014 22:59:45 +0200 +Subject: [PATCH 155/158] MIPS: BCM47XX: Make ssb init NVRAM instead of bcm47xx + polling it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This makes NVRAM code less bcm47xx/ssb specific allowing it to become a +standalone driver in the future. A similar patch for bcma will follow +when it's ready. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/7612/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 30 +++++++--------------- + arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | 1 + + drivers/ssb/driver_mipscore.c | 14 +++++++++- + 3 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index e07976b..fecc5ae 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -98,7 +98,14 @@ found: + return 0; + } + +-static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) ++/* ++ * On bcm47xx we need access to the NVRAM very early, so we can't use mtd ++ * subsystem to access flash. We can't even use platform device / driver to ++ * store memory offset. ++ * To handle this we provide following symbol. It's supposed to be called as ++ * soon as we get info about flash device, before any NVRAM entry is needed. ++ */ ++int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + { + void __iomem *iobase; + int err; +@@ -114,25 +121,6 @@ static int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + return err; + } + +-#ifdef CONFIG_BCM47XX_SSB +-static int nvram_init_ssb(void) +-{ +- struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; +- u32 base; +- u32 lim; +- +- if (mcore->pflash.present) { +- base = mcore->pflash.window; +- lim = mcore->pflash.window_size; +- } else { +- pr_err("Couldn't find supported flash memory\n"); +- return -ENXIO; +- } +- +- return bcm47xx_nvram_init_from_mem(base, lim); +-} +-#endif +- + #ifdef CONFIG_BCM47XX_BCMA + static int nvram_init_bcma(void) + { +@@ -168,7 +156,7 @@ static int nvram_init(void) + switch (bcm47xx_bus_type) { + #ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: +- return nvram_init_ssb(); ++ break; + #endif + #ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: +diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +index 36a3fc1..676be22 100644 +--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h ++++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +@@ -32,6 +32,7 @@ struct nvram_header { + #define NVRAM_MAX_VALUE_LEN 255 + #define NVRAM_MAX_PARAM_LEN 64 + ++int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); + extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); + + static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) +diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c +index 0907706..7b986f9 100644 +--- a/drivers/ssb/driver_mipscore.c ++++ b/drivers/ssb/driver_mipscore.c +@@ -15,6 +15,9 @@ + #include + #include + #include ++#ifdef CONFIG_BCM47XX ++#include ++#endif + + #include "ssb_private.h" + +@@ -210,6 +213,7 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore) + static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) + { + struct ssb_bus *bus = mcore->dev->bus; ++ struct ssb_sflash *sflash = &mcore->sflash; + struct ssb_pflash *pflash = &mcore->pflash; + + /* When there is no chipcommon on the bus there is 4MB flash */ +@@ -242,7 +246,15 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) + } + + ssb_pflash: +- if (pflash->present) { ++ if (sflash->present) { ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(sflash->window, sflash->size); ++#endif ++ } else if (pflash->present) { ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size); ++#endif ++ + ssb_pflash_data.width = pflash->buswidth; + ssb_pflash_resource.start = pflash->window; + ssb_pflash_resource.end = pflash->window + pflash->window_size; +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.18/032-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch b/target/linux/brcm47xx/patches-3.18/032-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch new file mode 100644 index 0000000000..a616fcc0e0 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.18/032-MIPS-BCM47XX-Make-bcma-init-NVRAM-instead-of-bcm47xx.patch @@ -0,0 +1,113 @@ +From 7177efc5b030012c54c2e217c9d6decc0bcc1c53 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 13:30:23 +0100 +Subject: [PATCH 156/158] MIPS: BCM47XX: Make bcma init NVRAM instead of + bcm47xx polling it +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This drops ssb/bcma dependency and will allow us to make it a standalone +driver. + +Signed-off-by: Rafał Miłecki +Cc: linux-mips@linux-mips.org +Cc: Hauke Mehrtens +Patchwork: https://patchwork.linux-mips.org/patch/8233/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/nvram.c | 42 ++---------------------------------------- + drivers/bcma/driver_mips.c | 13 +++++++++++-- + 2 files changed, 13 insertions(+), 42 deletions(-) + +diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c +index fecc5ae..21712fb 100644 +--- a/arch/mips/bcm47xx/nvram.c ++++ b/arch/mips/bcm47xx/nvram.c +@@ -121,48 +121,10 @@ int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) + return err; + } + +-#ifdef CONFIG_BCM47XX_BCMA +-static int nvram_init_bcma(void) +-{ +- struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; +- u32 base; +- u32 lim; +- +-#ifdef CONFIG_BCMA_NFLASH +- if (cc->nflash.boot) { +- base = BCMA_SOC_FLASH1; +- lim = BCMA_SOC_FLASH1_SZ; +- } else +-#endif +- if (cc->pflash.present) { +- base = cc->pflash.window; +- lim = cc->pflash.window_size; +-#ifdef CONFIG_BCMA_SFLASH +- } else if (cc->sflash.present) { +- base = cc->sflash.window; +- lim = cc->sflash.size; +-#endif +- } else { +- pr_err("Couldn't find supported flash memory\n"); +- return -ENXIO; +- } +- +- return bcm47xx_nvram_init_from_mem(base, lim); +-} +-#endif +- + static int nvram_init(void) + { +- switch (bcm47xx_bus_type) { +-#ifdef CONFIG_BCM47XX_SSB +- case BCM47XX_BUS_TYPE_SSB: +- break; +-#endif +-#ifdef CONFIG_BCM47XX_BCMA +- case BCM47XX_BUS_TYPE_BCMA: +- return nvram_init_bcma(); +-#endif +- } ++ /* TODO: Look for MTD "nvram" partition */ ++ + return -ENXIO; + } + +diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c +index 004d6aa..8a653dc 100644 +--- a/drivers/bcma/driver_mips.c ++++ b/drivers/bcma/driver_mips.c +@@ -20,6 +20,9 @@ + #include + #include + #include ++#ifdef CONFIG_BCM47XX ++#include ++#endif + + enum bcma_boot_dev { + BCMA_BOOT_DEV_UNK = 0, +@@ -316,10 +319,16 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) + switch (boot_dev) { + case BCMA_BOOT_DEV_PARALLEL: + case BCMA_BOOT_DEV_SERIAL: +- /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */ ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2, ++ BCMA_SOC_FLASH2_SZ); ++#endif + break; + case BCMA_BOOT_DEV_NAND: +- /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */ ++#ifdef CONFIG_BCM47XX ++ bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1, ++ BCMA_SOC_FLASH1_SZ); ++#endif + break; + default: + break; +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.18/033-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch b/target/linux/brcm47xx/patches-3.18/033-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch new file mode 100644 index 0000000000..fe4962993b --- /dev/null +++ b/target/linux/brcm47xx/patches-3.18/033-MIPS-BCM47XX-Move-SPROM-fallback-code-into-sprom.c.patch @@ -0,0 +1,216 @@ +From a59da8fb3b2a1f2df5f871464e43cd5b6ca6ceb1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 12:52:02 +0100 +Subject: [PATCH 157/158] MIPS: BCM47XX: Move SPROM fallback code into sprom.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is some general cleanup as well as preparing sprom.c to become a +standalone driver. We will need this for bcm53xx ARM arch support. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/8232/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/bcm47xx_private.h | 3 ++ + arch/mips/bcm47xx/setup.c | 58 ++----------------------------- + arch/mips/bcm47xx/sprom.c | 68 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 73 insertions(+), 56 deletions(-) + +diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h +index f1cc9d0..12a112d 100644 +--- a/arch/mips/bcm47xx/bcm47xx_private.h ++++ b/arch/mips/bcm47xx/bcm47xx_private.h +@@ -6,6 +6,9 @@ + /* prom.c */ + void __init bcm47xx_prom_highmem_init(void); + ++/* sprom.c */ ++void bcm47xx_sprom_register_fallbacks(void); ++ + /* buttons.c */ + int __init bcm47xx_buttons_register(void); + +diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c +index c00585d..444c65a 100644 +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) + } + + #ifdef CONFIG_BCM47XX_SSB +-static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) +-{ +- char prefix[10]; +- +- if (bus->bustype == SSB_BUSTYPE_PCI) { +- memset(out, 0, sizeof(struct ssb_sprom)); +- snprintf(prefix, sizeof(prefix), "pci/%u/%u/", +- bus->host_pci->bus->number + 1, +- PCI_SLOT(bus->host_pci->devfn)); +- bcm47xx_fill_sprom(out, prefix, false); +- return 0; +- } else { +- printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); +- return -EINVAL; +- } +-} +- + static int bcm47xx_get_invariants(struct ssb_bus *bus, + struct ssb_init_invariants *iv) + { +@@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) + char buf[100]; + struct ssb_mipscore *mcore; + +- err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); +- if (err) +- printk(KERN_WARNING "bcm47xx: someone else already registered" +- " a ssb SPROM callback handler (err %d)\n", err); +- + err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, + bcm47xx_get_invariants); + if (err) +@@ -171,44 +149,10 @@ static void __init bcm47xx_register_ssb(void) + #endif + + #ifdef CONFIG_BCM47XX_BCMA +-static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) +-{ +- char prefix[10]; +- struct bcma_device *core; +- +- switch (bus->hosttype) { +- case BCMA_HOSTTYPE_PCI: +- memset(out, 0, sizeof(struct ssb_sprom)); +- snprintf(prefix, sizeof(prefix), "pci/%u/%u/", +- bus->host_pci->bus->number + 1, +- PCI_SLOT(bus->host_pci->devfn)); +- bcm47xx_fill_sprom(out, prefix, false); +- return 0; +- case BCMA_HOSTTYPE_SOC: +- memset(out, 0, sizeof(struct ssb_sprom)); +- core = bcma_find_core(bus, BCMA_CORE_80211); +- if (core) { +- snprintf(prefix, sizeof(prefix), "sb/%u/", +- core->core_index); +- bcm47xx_fill_sprom(out, prefix, true); +- } else { +- bcm47xx_fill_sprom(out, NULL, false); +- } +- return 0; +- default: +- pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); +- return -EINVAL; +- } +-} +- + static void __init bcm47xx_register_bcma(void) + { + int err; + +- err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); +- if (err) +- pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); +- + err = bcma_host_soc_register(&bcm47xx_bus.bcma); + if (err) + panic("Failed to register BCMA bus (err %d)", err); +@@ -229,6 +173,7 @@ void __init plat_mem_setup(void) + printk(KERN_INFO "bcm47xx: using bcma bus\n"); + #ifdef CONFIG_BCM47XX_BCMA + bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; ++ bcm47xx_sprom_register_fallbacks(); + bcm47xx_register_bcma(); + bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); + #ifdef CONFIG_HIGHMEM +@@ -239,6 +184,7 @@ void __init plat_mem_setup(void) + printk(KERN_INFO "bcm47xx: using ssb bus\n"); + #ifdef CONFIG_BCM47XX_SSB + bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; ++ bcm47xx_sprom_register_fallbacks(); + bcm47xx_register_ssb(); + bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); + #endif +diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c +index 41226b6..e772e77 100644 +--- a/arch/mips/bcm47xx/sprom.c ++++ b/arch/mips/bcm47xx/sprom.c +@@ -801,3 +801,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, + nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); + } + #endif ++ ++#if defined(CONFIG_BCM47XX_SSB) ++static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) ++{ ++ char prefix[10]; ++ ++ if (bus->bustype == SSB_BUSTYPE_PCI) { ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ snprintf(prefix, sizeof(prefix), "pci/%u/%u/", ++ bus->host_pci->bus->number + 1, ++ PCI_SLOT(bus->host_pci->devfn)); ++ bcm47xx_fill_sprom(out, prefix, false); ++ return 0; ++ } else { ++ pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); ++ return -EINVAL; ++ } ++} ++#endif ++ ++#if defined(CONFIG_BCM47XX_BCMA) ++static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) ++{ ++ char prefix[10]; ++ struct bcma_device *core; ++ ++ switch (bus->hosttype) { ++ case BCMA_HOSTTYPE_PCI: ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ snprintf(prefix, sizeof(prefix), "pci/%u/%u/", ++ bus->host_pci->bus->number + 1, ++ PCI_SLOT(bus->host_pci->devfn)); ++ bcm47xx_fill_sprom(out, prefix, false); ++ return 0; ++ case BCMA_HOSTTYPE_SOC: ++ memset(out, 0, sizeof(struct ssb_sprom)); ++ core = bcma_find_core(bus, BCMA_CORE_80211); ++ if (core) { ++ snprintf(prefix, sizeof(prefix), "sb/%u/", ++ core->core_index); ++ bcm47xx_fill_sprom(out, prefix, true); ++ } else { ++ bcm47xx_fill_sprom(out, NULL, false); ++ } ++ return 0; ++ default: ++ pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); ++ return -EINVAL; ++ } ++} ++#endif ++ ++/* ++ * On bcm47xx we need to register SPROM fallback handler very early, so we can't ++ * use anything like platform device / driver for this. ++ */ ++void bcm47xx_sprom_register_fallbacks(void) ++{ ++#if defined(CONFIG_BCM47XX_SSB) ++ if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) ++ pr_warn("Failed to registered ssb SPROM handler\n"); ++#endif ++ ++#if defined(CONFIG_BCM47XX_BCMA) ++ if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) ++ pr_warn("Failed to registered bcma SPROM handler\n"); ++#endif ++} +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.18/034-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch b/target/linux/brcm47xx/patches-3.18/034-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch new file mode 100644 index 0000000000..54680de0b7 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.18/034-MIPS-BCM47XX-Initialize-bcma-bus-later-with-mm-avail.patch @@ -0,0 +1,120 @@ +From e5810fa0c1bed16fdfb408862a2e17e962ec5cf6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 28 Oct 2014 14:40:38 +0100 +Subject: [PATCH 158/158] MIPS: BCM47XX: Initialize bcma bus later (with mm + available) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Initializaion with memory allocator available will be much simpler, this +will allow cleanup in the bcma code. + +Signed-off-by: Rafał Miłecki +Acked-by: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/8234/ +Signed-off-by: Ralf Baechle +--- + arch/mips/bcm47xx/bcm47xx_private.h | 3 +++ + arch/mips/bcm47xx/irq.c | 8 ++++++++ + arch/mips/bcm47xx/setup.c | 33 +++++++++++++++++++++++++++------ + 3 files changed, 38 insertions(+), 6 deletions(-) + +diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h +index 12a112d..ea909a5 100644 +--- a/arch/mips/bcm47xx/bcm47xx_private.h ++++ b/arch/mips/bcm47xx/bcm47xx_private.h +@@ -15,6 +15,9 @@ int __init bcm47xx_buttons_register(void); + /* leds.c */ + void __init bcm47xx_leds_register(void); + ++/* setup.c */ ++void __init bcm47xx_bus_setup(void); ++ + /* workarounds.c */ + void __init bcm47xx_workarounds(void); + +diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c +index e0585b7..21b4497 100644 +--- a/arch/mips/bcm47xx/irq.c ++++ b/arch/mips/bcm47xx/irq.c +@@ -22,6 +22,8 @@ + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#include "bcm47xx_private.h" ++ + #include + #include + #include +@@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) + + void __init arch_init_irq(void) + { ++ /* ++ * This is the first arch callback after mm_init (we can use kmalloc), ++ * so let's finish bus initialization now. ++ */ ++ bcm47xx_bus_setup(); ++ + #ifdef CONFIG_BCM47XX_BCMA + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { + bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, +diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c +index 444c65a..e43b504 100644 +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -156,15 +156,14 @@ static void __init bcm47xx_register_bcma(void) + err = bcma_host_soc_register(&bcm47xx_bus.bcma); + if (err) + panic("Failed to register BCMA bus (err %d)", err); +- +- err = bcma_host_soc_init(&bcm47xx_bus.bcma); +- if (err) +- panic("Failed to initialize BCMA bus (err %d)", err); +- +- bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); + } + #endif + ++/* ++ * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed ++ * to detect memory and record it with add_memory_region. ++ * Any extra initializaion performed here must not use kmalloc or bootmem. ++ */ + void __init plat_mem_setup(void) + { + struct cpuinfo_mips *c = ¤t_cpu_data; +@@ -193,6 +192,28 @@ void __init plat_mem_setup(void) + _machine_restart = bcm47xx_machine_restart; + _machine_halt = bcm47xx_machine_halt; + pm_power_off = bcm47xx_machine_halt; ++} ++ ++/* ++ * This finishes bus initialization doing things that were not possible without ++ * kmalloc. Make sure to call it late enough (after mm_init). ++ */ ++void __init bcm47xx_bus_setup(void) ++{ ++#ifdef CONFIG_BCM47XX_BCMA ++ if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { ++ int err; ++ ++ err = bcma_host_soc_init(&bcm47xx_bus.bcma); ++ if (err) ++ panic("Failed to initialize BCMA bus (err %d)", err); ++ ++ bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, ++ NULL); ++ } ++#endif ++ ++ /* With bus initialized we can access NVRAM and detect the board */ + bcm47xx_board_detect(); + mips_set_machine_name(bcm47xx_board_get_name()); + } +-- +1.8.4.5 + diff --git a/target/linux/brcm47xx/patches-3.18/820-wgt634u-nvram-fix.patch b/target/linux/brcm47xx/patches-3.18/820-wgt634u-nvram-fix.patch index e2bbdcc15f..ea002fe732 100644 --- a/target/linux/brcm47xx/patches-3.18/820-wgt634u-nvram-fix.patch +++ b/target/linux/brcm47xx/patches-3.18/820-wgt634u-nvram-fix.patch @@ -251,17 +251,17 @@ out the configuration than the in kernel cfe config reader. +static int cfe_env; +extern char *cfe_env_get(char *nv_buf, const char *name); - static u32 find_nvram_size(u32 end) + static u32 find_nvram_size(void __iomem *end) { -@@ -46,6 +48,26 @@ static int nvram_find_and_copy(u32 base, - u32 *src, *dst; - u32 size; +@@ -51,6 +53,26 @@ static int nvram_find_and_copy(void __io + return -EEXIST; + } + cfe_env = 0; + + /* XXX: hack for supporting the CFE environment stuff on WGT634U */ + if (lim >= 8 * 1024 * 1024) { -+ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ src = (u32 *) iobase + 8 * 1024 * 1024 - 0x2000; + dst = (u32 *) nvram_buf; + + if ((*src & 0xff00ff) == 0x000001) { @@ -280,7 +280,7 @@ out the configuration than the in kernel cfe config reader. /* TODO: when nvram is on nand flash check for bad blocks first. */ off = FLASH_MIN; while (off <= lim) { -@@ -172,6 +194,13 @@ int bcm47xx_nvram_getenv(char *name, cha +@@ -142,6 +164,13 @@ int bcm47xx_nvram_getenv(char *name, cha return err; } diff --git a/target/linux/brcm47xx/patches-3.18/830-huawei_e970_support.patch b/target/linux/brcm47xx/patches-3.18/830-huawei_e970_support.patch index 5425d049cb..bab051a647 100644 --- a/target/linux/brcm47xx/patches-3.18/830-huawei_e970_support.patch +++ b/target/linux/brcm47xx/patches-3.18/830-huawei_e970_support.patch @@ -8,7 +8,7 @@ #include #include #include -@@ -282,6 +283,33 @@ static struct fixed_phy_status bcm47xx_f +@@ -249,6 +250,33 @@ static struct fixed_phy_status bcm47xx_f .duplex = DUPLEX_FULL, }; @@ -42,7 +42,7 @@ static int __init bcm47xx_register_bus_complete(void) { switch (bcm47xx_bus_type) { -@@ -301,6 +329,7 @@ static int __init bcm47xx_register_bus_c +@@ -268,6 +296,7 @@ static int __init bcm47xx_register_bus_c bcm47xx_workarounds(); fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); diff --git a/target/linux/brcm47xx/patches-3.18/980-wnr834b_no_cardbus_invariant.patch b/target/linux/brcm47xx/patches-3.18/980-wnr834b_no_cardbus_invariant.patch index 8bab5f09bf..86c00c93a3 100644 --- a/target/linux/brcm47xx/patches-3.18/980-wnr834b_no_cardbus_invariant.patch +++ b/target/linux/brcm47xx/patches-3.18/980-wnr834b_no_cardbus_invariant.patch @@ -1,6 +1,6 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -136,6 +136,10 @@ static int bcm47xx_get_invariants(struct +@@ -119,6 +119,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); -- 2.25.1