diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/ath79/dev-usb.c | 31 | ||||
-rw-r--r-- | arch/mips/bcm47xx/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/bcm47xx/nvram.c | 3 | ||||
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 188 | ||||
-rw-r--r-- | arch/mips/bcm47xx/sprom.c | 620 | ||||
-rw-r--r-- | arch/mips/bcm63xx/setup.c | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/highmem.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/irq.h | 5 | ||||
-rw-r--r-- | arch/mips/include/asm/jump_label.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 3 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-bcm47xx/nvram.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/socket.h | 4 | ||||
-rw-r--r-- | arch/mips/jz4740/board-qi_lb60.c | 6 | ||||
-rw-r--r-- | arch/mips/kernel/perf_event_mipsxx.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/prom.c | 14 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/highmem.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 8 | ||||
-rw-r--r-- | arch/mips/pci/pci-bcm47xx.c | 49 |
21 files changed, 758 insertions, 200 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5ab6e89603c..edbbae17e82 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2327,6 +2327,7 @@ config USE_OF bool "Flattened Device Tree support" select OF select OF_EARLY_FLATTREE + select IRQ_DOMAIN help Include support for flattened device tree machine descriptions. diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index 002d6d2afe0..36e9570e7bc 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -17,6 +17,8 @@ #include <linux/irq.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> +#include <linux/usb/ehci_pdriver.h> +#include <linux/usb/ohci_pdriver.h> #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> @@ -36,14 +38,19 @@ static struct resource ath79_ohci_resources[] = { }; static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32); + +static struct usb_ohci_pdata ath79_ohci_pdata = { +}; + static struct platform_device ath79_ohci_device = { - .name = "ath79-ohci", + .name = "ohci-platform", .id = -1, .resource = ath79_ohci_resources, .num_resources = ARRAY_SIZE(ath79_ohci_resources), .dev = { .dma_mask = &ath79_ohci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &ath79_ohci_pdata, }, }; @@ -60,8 +67,20 @@ static struct resource ath79_ehci_resources[] = { }; static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); + +static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { + .has_synopsys_hc_bug = 1, + .port_power_off = 1, +}; + +static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { + .caps_offset = 0x100, + .has_tt = 1, + .port_power_off = 1, +}; + static struct platform_device ath79_ehci_device = { - .name = "ath79-ehci", + .name = "ehci-platform", .id = -1, .resource = ath79_ehci_resources, .num_resources = ARRAY_SIZE(ath79_ehci_resources), @@ -101,7 +120,7 @@ static void __init ath79_usb_setup(void) ath79_ehci_resources[0].start = AR71XX_EHCI_BASE; ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1; - ath79_ehci_device.name = "ar71xx-ehci"; + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1; platform_device_register(&ath79_ehci_device); } @@ -142,7 +161,7 @@ static void __init ar724x_usb_setup(void) ath79_ehci_resources[0].start = AR724X_EHCI_BASE; ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1; - ath79_ehci_device.name = "ar724x-ehci"; + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -159,7 +178,7 @@ static void __init ar913x_usb_setup(void) ath79_ehci_resources[0].start = AR913X_EHCI_BASE; ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1; - ath79_ehci_device.name = "ar913x-ehci"; + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } @@ -176,7 +195,7 @@ static void __init ar933x_usb_setup(void) ath79_ehci_resources[0].start = AR933X_EHCI_BASE; ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1; - ath79_ehci_device.name = "ar933x-ehci"; + ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2; platform_device_register(&ath79_ehci_device); } diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index 4add17349ff..4389de182eb 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -3,5 +3,5 @@ # under Linux. # -obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o +obj-y += gpio.o irq.o nvram.o prom.o serial.o setup.o time.o sprom.o obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index a84e3bb7387..d43ceff5be4 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -107,8 +107,7 @@ int nvram_getenv(char *name, char *val, size_t val_len) value = eq + 1; if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) { - snprintf(val, val_len, "%s", value); - return 0; + return snprintf(val, val_len, "%s", value); } } return NVRAM_ERR_ENVNOTFOUND; diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index aab6b0c40a7..19780aa9170 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -3,7 +3,7 @@ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> * Copyright (C) 2006 Michael Buesch <m@bues.ch> * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> - * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de> + * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> * * 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 @@ -85,156 +85,7 @@ static void bcm47xx_machine_halt(void) } #ifdef CONFIG_BCM47XX_SSB -#define READ_FROM_NVRAM(_outvar, name, buf) \ - if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\ - sprom->_outvar = simple_strtoul(buf, NULL, 0); - -#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \ - if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \ - nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\ - sprom->_outvar = simple_strtoul(buf, NULL, 0); - -static inline int nvram_getprefix(const char *prefix, char *name, - char *buf, int len) -{ - if (prefix) { - char key[100]; - - snprintf(key, sizeof(key), "%s%s", prefix, name); - return nvram_getenv(key, buf, len); - } - - return nvram_getenv(name, buf, len); -} - -static u32 nvram_getu32(const char *name, char *buf, int len) -{ - int rv; - char key[100]; - u16 var0, var1; - - snprintf(key, sizeof(key), "%s0", name); - rv = nvram_getenv(key, buf, len); - /* return 0 here so this looks like unset */ - if (rv < 0) - return 0; - var0 = simple_strtoul(buf, NULL, 0); - - snprintf(key, sizeof(key), "%s1", name); - rv = nvram_getenv(key, buf, len); - if (rv < 0) - return 0; - var1 = simple_strtoul(buf, NULL, 0); - return var1 << 16 | var0; -} - -static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) -{ - char buf[100]; - u32 boardflags; - - memset(sprom, 0, sizeof(struct ssb_sprom)); - - sprom->revision = 1; /* Fallback: Old hardware does not define this. */ - READ_FROM_NVRAM(revision, "sromrev", buf); - if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 || - nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->il0mac); - if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->et0mac); - if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0) - nvram_parse_macaddr(buf, sprom->et1mac); - READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); - READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); - READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); - READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); - READ_FROM_NVRAM(board_rev, "boardrev", buf); - READ_FROM_NVRAM(country_code, "ccode", buf); - READ_FROM_NVRAM(ant_available_a, "aa5g", buf); - READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); - READ_FROM_NVRAM(pa0b0, "pa0b0", buf); - READ_FROM_NVRAM(pa0b1, "pa0b1", buf); - READ_FROM_NVRAM(pa0b2, "pa0b2", buf); - READ_FROM_NVRAM(pa1b0, "pa1b0", buf); - READ_FROM_NVRAM(pa1b1, "pa1b1", buf); - READ_FROM_NVRAM(pa1b2, "pa1b2", buf); - READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); - READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); - READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); - READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); - READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); - READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); - READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf); - READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf); - READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf); - READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf); - READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf); - READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf); - READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf); - READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf); - READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf); - READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf); - READ_FROM_NVRAM(tri2g, "tri2g", buf); - READ_FROM_NVRAM(tri5gl, "tri5gl", buf); - READ_FROM_NVRAM(tri5g, "tri5g", buf); - READ_FROM_NVRAM(tri5gh, "tri5gh", buf); - READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf); - READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf); - READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf); - READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf); - READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf); - READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf); - READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf); - READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf); - READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf); - READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf); - READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf); - READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf); - READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf); - READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf); - READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf); - READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf); - READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); - READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); - READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); - READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); - READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); - READ_FROM_NVRAM(bxa2g, "bxa2g", buf); - READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); - READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); - READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); - READ_FROM_NVRAM(bxa5g, "bxa5g", buf); - READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); - - sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf)); - sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf)); - sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf)); - sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf)); - - READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf); - READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf); - memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24, - sizeof(sprom->antenna_gain.ghz5)); - - if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) { - boardflags = simple_strtoul(buf, NULL, 0); - if (boardflags) { - sprom->boardflags_lo = (boardflags & 0x0000FFFFU); - sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; - } - } - if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) { - boardflags = simple_strtoul(buf, NULL, 0); - if (boardflags) { - sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); - sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; - } - } -} - -int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) +static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) { char prefix[10]; @@ -251,7 +102,7 @@ int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out) } static int bcm47xx_get_invariants(struct ssb_bus *bus, - struct ssb_init_invariants *iv) + struct ssb_init_invariants *iv) { char buf[20]; @@ -281,7 +132,7 @@ static void __init bcm47xx_register_ssb(void) char buf[100]; struct ssb_mipscore *mcore; - err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom); + 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); @@ -308,10 +159,41 @@ 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: + snprintf(prefix, sizeof(prefix), "pci/%u/%u/", + bus->host_pci->bus->number + 1, + PCI_SLOT(bus->host_pci->devfn)); + bcm47xx_fill_sprom(out, prefix); + return 0; + case BCMA_HOSTTYPE_SOC: + bcm47xx_fill_sprom_ethernet(out, NULL); + core = bcma_find_core(bus, BCMA_CORE_80211); + if (core) { + snprintf(prefix, sizeof(prefix), "sb/%u/", + core->core_index); + bcm47xx_fill_sprom(out, prefix); + } + 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 initialize BCMA bus (err %d)", err); diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c new file mode 100644 index 00000000000..5c8dcd2a8a9 --- /dev/null +++ b/arch/mips/bcm47xx/sprom.c @@ -0,0 +1,620 @@ +/* + * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2006 Michael Buesch <m@bues.ch> + * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> + * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <bcm47xx.h> +#include <nvram.h> + +static void create_key(const char *prefix, const char *postfix, + const char *name, char *buf, int len) +{ + if (prefix && postfix) + snprintf(buf, len, "%s%s%s", prefix, name, postfix); + else if (prefix) + snprintf(buf, len, "%s%s", prefix, name); + else if (postfix) + snprintf(buf, len, "%s%s", name, postfix); + else + snprintf(buf, len, "%s", name); +} + +#define NVRAM_READ_VAL(type) \ +static void nvram_read_ ## type (const char *prefix, \ + const char *postfix, const char *name, \ + type *val, type allset) \ +{ \ + char buf[100]; \ + char key[40]; \ + int err; \ + type var; \ + \ + create_key(prefix, postfix, name, key, sizeof(key)); \ + \ + err = nvram_getenv(key, buf, sizeof(buf)); \ + if (err < 0) \ + return; \ + err = kstrto ## type (buf, 0, &var); \ + if (err) { \ + pr_warn("can not parse nvram name %s with value %s" \ + " got %i", key, buf, err); \ + return; \ + } \ + if (allset && var == allset) \ + return; \ + *val = var; \ +} + +NVRAM_READ_VAL(u8) +NVRAM_READ_VAL(s8) +NVRAM_READ_VAL(u16) +NVRAM_READ_VAL(u32) + +#undef NVRAM_READ_VAL + +static void nvram_read_u32_2(const char *prefix, const char *name, + u16 *val_lo, u16 *val_hi) +{ + char buf[100]; + char key[40]; + int err; + u32 val; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + err = kstrtou32(buf, 0, &val); + if (err) { + pr_warn("can not parse nvram name %s with value %s got %i", + key, buf, err); + return; + } + *val_lo = (val & 0x0000FFFFU); + *val_hi = (val & 0xFFFF0000U) >> 16; +} + +static void nvram_read_leddc(const char *prefix, const char *name, + u8 *leddc_on_time, u8 *leddc_off_time) +{ + char buf[100]; + char key[40]; + int err; + u32 val; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + err = kstrtou32(buf, 0, &val); + if (err) { + pr_warn("can not parse nvram name %s with value %s got %i", + key, buf, err); + return; + } + + if (val == 0xffff || val == 0xffffffff) + return; + + *leddc_on_time = val & 0xff; + *leddc_off_time = (val >> 16) & 0xff; +} + +static void nvram_read_macaddr(const char *prefix, const char *name, + u8 (*val)[6]) +{ + char buf[100]; + char key[40]; + int err; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + nvram_parse_macaddr(buf, *val); +} + +static void nvram_read_alpha2(const char *prefix, const char *name, + char (*val)[2]) +{ + char buf[10]; + char key[40]; + int err; + + create_key(prefix, NULL, name, key, sizeof(key)); + + err = nvram_getenv(key, buf, sizeof(buf)); + if (err < 0) + return; + if (buf[0] == '0') + return; + if (strlen(buf) > 2) { + pr_warn("alpha2 is too long %s", buf); + return; + } + memcpy(val, buf, sizeof(val)); +} + +static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0); + nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0); + nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff); + nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff); + nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff); + nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff); + nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0); + nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0); + nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0); + nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0); + nvram_read_alpha2(prefix, "ccode", &sprom->alpha2); +} + +static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0); + nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0); + nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0); + nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0); + nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0); + nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0); + nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0); + nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0); + nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0); + nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0); +} + +static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0); + nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0); +} + +static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0); + nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0); + nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0); + nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0); + nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0); + nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0); + nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0); + nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0); + nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0); +} + +static void bcm47xx_fill_sprom_r2(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); +} + +static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0); + nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0); + nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0); + nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0); + nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0); + nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0); + nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0); + nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0); + nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0); + nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0); + nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0); + nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0); + nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0); + nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0); +} + +static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); + nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, + &sprom->leddc_off_time); +} + +static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, + const char *prefix) +{ + nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo, + &sprom->boardflags_hi); + nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo, + &sprom->boardflags2_hi); + nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0); + nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0); + nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0); + nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0); + nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf); + nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf); + nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff); + nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, + &sprom->leddc_off_time); +} + +static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0); + nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0); + nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0); + nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0); + nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0); + nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0); + nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0); + nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0); +} + +static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0); + nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0); + nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0); + nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0); + nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0); + nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0); + nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0); + nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0); + nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0); + nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0); + nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0); + nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0); + nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0); + nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0); + nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0); + nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0); +} + +static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0); + nvram_read_u8(prefix, NULL, "extpagain2g", + &sprom->fem.ghz2.extpa_gain, 0); + nvram_read_u8(prefix, NULL, "pdetrange2g", + &sprom->fem.ghz2.pdet_range, 0); + nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0); + nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0); + nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0); + nvram_read_u8(prefix, NULL, "extpagain5g", + &sprom->fem.ghz5.extpa_gain, 0); + nvram_read_u8(prefix, NULL, "pdetrange5g", + &sprom->fem.ghz5.pdet_range, 0); + nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0); + nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0); + nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0); + nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0); + nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0); + nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0); + nvram_read_u8(prefix, NULL, "tempsense_slope", + &sprom->tempsense_slope, 0); + nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0); + nvram_read_u8(prefix, NULL, "tempsense_option", + &sprom->tempsense_option, 0); + nvram_read_u8(prefix, NULL, "freqoffset_corr", + &sprom->freqoffset_corr, 0); + nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0); + nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0); + nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0); + nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0); + nvram_read_u8(prefix, NULL, "phycal_tempdelta", + &sprom->phycal_tempdelta, 0); + nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0); + nvram_read_u8(prefix, NULL, "temps_hysteresis", + &sprom->temps_hysteresis, 0); + nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0); + nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga0", + &sprom->rxgainerr2ga[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga1", + &sprom->rxgainerr2ga[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr2ga2", + &sprom->rxgainerr2ga[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla0", + &sprom->rxgainerr5gla[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla1", + &sprom->rxgainerr5gla[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gla2", + &sprom->rxgainerr5gla[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma0", + &sprom->rxgainerr5gma[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma1", + &sprom->rxgainerr5gma[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gma2", + &sprom->rxgainerr5gma[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha0", + &sprom->rxgainerr5gha[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha1", + &sprom->rxgainerr5gha[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gha2", + &sprom->rxgainerr5gha[2], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua0", + &sprom->rxgainerr5gua[0], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua1", + &sprom->rxgainerr5gua[1], 0); + nvram_read_u8(prefix, NULL, "rxgainerr5gua2", + &sprom->rxgainerr5gua[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla0", + &sprom->noiselvl5gla[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla1", + &sprom->noiselvl5gla[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gla2", + &sprom->noiselvl5gla[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma0", + &sprom->noiselvl5gma[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma1", + &sprom->noiselvl5gma[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gma2", + &sprom->noiselvl5gma[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha0", + &sprom->noiselvl5gha[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha1", + &sprom->noiselvl5gha[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gha2", + &sprom->noiselvl5gha[2], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua0", + &sprom->noiselvl5gua[0], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua1", + &sprom->noiselvl5gua[1], 0); + nvram_read_u8(prefix, NULL, "noiselvl5gua2", + &sprom->noiselvl5gua[2], 0); + nvram_read_u8(prefix, NULL, "pcieingress_war", + &sprom->pcieingress_war, 0); +} + +static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0); + nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw202gpo", + &sprom->legofdmbw202gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo", + &sprom->legofdmbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205glpo", + &sprom->legofdmbw205glpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo", + &sprom->legofdmbw20ul5glpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205gmpo", + &sprom->legofdmbw205gmpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo", + &sprom->legofdmbw20ul5gmpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw205ghpo", + &sprom->legofdmbw205ghpo, 0); + nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo", + &sprom->legofdmbw20ul5ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo", + &sprom->mcsbw20ul5glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo", + &sprom->mcsbw20ul5gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo", + &sprom->mcsbw20ul5ghpo, 0); + nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0); + nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0); + nvram_read_u16(prefix, NULL, "legofdm40duppo", + &sprom->legofdm40duppo, 0); + nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0); + nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0); +} + +static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, + const char *prefix) +{ + char postfix[2]; + int i; + + for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { + struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; + snprintf(postfix, sizeof(postfix), "%i", i); + nvram_read_u8(prefix, postfix, "maxp2ga", + &pwr_info->maxpwr_2g, 0); + nvram_read_u8(prefix, postfix, "itt2ga", + &pwr_info->itssi_2g, 0); + nvram_read_u8(prefix, postfix, "itt5ga", + &pwr_info->itssi_5g, 0); + nvram_read_u16(prefix, postfix, "pa2gw0a", + &pwr_info->pa_2g[0], 0); + nvram_read_u16(prefix, postfix, "pa2gw1a", + &pwr_info->pa_2g[1], 0); + nvram_read_u16(prefix, postfix, "pa2gw2a", + &pwr_info->pa_2g[2], 0); + nvram_read_u8(prefix, postfix, "maxp5ga", + &pwr_info->maxpwr_5g, 0); + nvram_read_u8(prefix, postfix, "maxp5gha", + &pwr_info->maxpwr_5gh, 0); + nvram_read_u8(prefix, postfix, "maxp5gla", + &pwr_info->maxpwr_5gl, 0); + nvram_read_u16(prefix, postfix, "pa5gw0a", + &pwr_info->pa_5g[0], 0); + nvram_read_u16(prefix, postfix, "pa5gw1a", + &pwr_info->pa_5g[1], 0); + nvram_read_u16(prefix, postfix, "pa5gw2a", + &pwr_info->pa_5g[2], 0); + nvram_read_u16(prefix, postfix, "pa5glw0a", + &pwr_info->pa_5gl[0], 0); + nvram_read_u16(prefix, postfix, "pa5glw1a", + &pwr_info->pa_5gl[1], 0); + nvram_read_u16(prefix, postfix, "pa5glw2a", + &pwr_info->pa_5gl[2], 0); + nvram_read_u16(prefix, postfix, "pa5ghw0a", + &pwr_info->pa_5gh[0], 0); + nvram_read_u16(prefix, postfix, "pa5ghw1a", + &pwr_info->pa_5gh[1], 0); + nvram_read_u16(prefix, postfix, "pa5ghw2a", + &pwr_info->pa_5gh[2], 0); + } +} + +static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, + const char *prefix) +{ + char postfix[2]; + int i; + + for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) { + struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i]; + snprintf(postfix, sizeof(postfix), "%i", i); + nvram_read_u16(prefix, postfix, "pa2gw3a", + &pwr_info->pa_2g[3], 0); + nvram_read_u16(prefix, postfix, "pa5gw3a", + &pwr_info->pa_5g[3], 0); + nvram_read_u16(prefix, postfix, "pa5glw3a", + &pwr_info->pa_5gl[3], 0); + nvram_read_u16(prefix, postfix, "pa5ghw3a", + &pwr_info->pa_5gh[3], 0); + } +} + +void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix) +{ + nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac); + nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0); + nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0); + + nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac); + nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0); + nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0); + + nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac); + nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac); +} + +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix) +{ + memset(sprom, 0, sizeof(struct ssb_sprom)); + + bcm47xx_fill_sprom_ethernet(sprom, prefix); + + nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0); + + switch (sprom->revision) { + case 1: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r1(sprom, prefix); + break; + case 2: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r2(sprom, prefix); + break; + case 3: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r3(sprom, prefix); + break; + case 4: + case 5: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r458(sprom, prefix); + bcm47xx_fill_sprom_r45(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + bcm47xx_fill_sprom_path_r45(sprom, prefix); + break; + case 8: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r458(sprom, prefix); + bcm47xx_fill_sprom_r89(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + break; + case 9: + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r2389(sprom, prefix); + bcm47xx_fill_sprom_r389(sprom, prefix); + bcm47xx_fill_sprom_r4589(sprom, prefix); + bcm47xx_fill_sprom_r89(sprom, prefix); + bcm47xx_fill_sprom_r9(sprom, prefix); + bcm47xx_fill_sprom_path_r4589(sprom, prefix); + break; + default: + pr_warn("Unsupported SPROM revision %d detected. Will extract" + " v1\n", sprom->revision); + sprom->revision = 1; + bcm47xx_fill_sprom_r1234589(sprom, prefix); + bcm47xx_fill_sprom_r12389(sprom, prefix); + bcm47xx_fill_sprom_r1(sprom, prefix); + } +} diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index d209f85d87b..356b05583e1 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -33,7 +33,7 @@ static void bcm6348_a1_reboot(void) u32 reg; /* soft reset all blocks */ - printk(KERN_INFO "soft-reseting all blocks ...\n"); + printk(KERN_INFO "soft-resetting all blocks ...\n"); reg = bcm_perf_readl(PERF_SOFTRESET_REG); reg &= ~SOFTRESET_6348_ALL; bcm_perf_writel(reg, PERF_SOFTRESET_REG); diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 77e644082a3..2d91888c9b7 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -47,7 +47,7 @@ extern void kunmap_high(struct page *page); extern void *kmap(struct page *page); extern void kunmap(struct page *page); -extern void *__kmap_atomic(struct page *page); +extern void *kmap_atomic(struct page *page); extern void __kunmap_atomic(void *kvaddr); extern void *kmap_atomic_pfn(unsigned long pfn); extern struct page *kmap_atomic_to_page(void *ptr); diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 2354c870a63..fb698dc09bc 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -11,15 +11,12 @@ #include <linux/linkage.h> #include <linux/smp.h> +#include <linux/irqdomain.h> #include <asm/mipsmtregs.h> #include <irq.h> -static inline void irq_dispose_mapping(unsigned int virq) -{ -} - #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) { diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h index 1881b316ca4..4d6d77ed9b9 100644 --- a/arch/mips/include/asm/jump_label.h +++ b/arch/mips/include/asm/jump_label.h @@ -20,7 +20,7 @@ #define WORD_INSN ".word" #endif -static __always_inline bool arch_static_branch(struct jump_label_key *key) +static __always_inline bool arch_static_branch(struct static_key *key) { asm goto("1:\tnop\n\t" "nop\n\t" diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index de95e0723e2..5ecaf47b34d 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -44,4 +44,7 @@ union bcm47xx_bus { extern union bcm47xx_bus bcm47xx_bus; extern enum bcm47xx_bus_type bcm47xx_bus_type; +void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix); +void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix); + #endif /* __ASM_BCM47XX_H */ diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index 184d5ecb5f5..69ef3efe06e 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h @@ -37,7 +37,7 @@ struct nvram_header { extern int nvram_getenv(char *name, char *val, size_t val_len); -static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) +static inline void nvram_parse_macaddr(char *buf, u8 macaddr[6]) { if (strchr(buf, ':')) sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h index ad5c0a7a02a..a2ed6fdad4e 100644 --- a/arch/mips/include/asm/socket.h +++ b/arch/mips/include/asm/socket.h @@ -84,6 +84,10 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ #define SO_WIFI_STATUS 41 #define SCM_WIFI_STATUS SO_WIFI_STATUS +#define SO_PEEK_OFF 42 + +/* Instruct lower device to use last 4-bytes of skb data as FCS */ +#define SO_NOFCS 43 #ifdef __KERNEL__ diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 639e3ce6c26..9a91fe9de69 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -418,6 +418,11 @@ static struct platform_device qi_lb60_charger_device = { }, }; +/* audio */ +static struct platform_device qi_lb60_audio_device = { + .name = "qi-lb60-audio", + .id = -1, +}; static struct platform_device *jz_platform_devices[] __initdata = { &jz4740_udc_device, @@ -434,6 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { &qi_lb60_gpio_keys, &qi_lb60_pwm_beeper, &qi_lb60_charger_device, + &qi_lb60_audio_device, }; static void __init board_gpio_setup(void) diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index e3b897acfbc..811084f4e42 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -606,6 +606,10 @@ static int mipspmu_event_init(struct perf_event *event) { int err = 0; + /* does not support taken branch sampling */ + if (has_branch_stack(event)) + return -EOPNOTSUPP; + switch (event->attr.type) { case PERF_TYPE_RAW: case PERF_TYPE_HARDWARE: diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 7955409051c..61f1cb45a1d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -80,9 +80,7 @@ void __noreturn cpu_idle(void) #endif rcu_idle_exit(); tick_nohz_idle_exit(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); + schedule_preempt_disabled(); } } diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 6b8b4208481..558b5395795 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -60,20 +60,6 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start, } #endif -/* - * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# - * - * Currently the mapping mechanism is trivial; simple flat hwirq numbers are - * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not - * supported. - */ -unsigned int irq_create_of_mapping(struct device_node *controller, - const u32 *intspec, unsigned int intsize) -{ - return intspec[0]; -} -EXPORT_SYMBOL_GPL(irq_create_of_mapping); - void __init early_init_devtree(void *params) { /* Setup flat device-tree pointer */ diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 4f9eb0b2303..c97087d12d0 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -498,7 +498,7 @@ static inline void local_r4k_flush_cache_page(void *args) if (map_coherent) vaddr = kmap_coherent(page, addr); else - vaddr = kmap_atomic(page, KM_USER0); + vaddr = kmap_atomic(page); addr = (unsigned long)vaddr; } @@ -521,7 +521,7 @@ static inline void local_r4k_flush_cache_page(void *args) if (map_coherent) kunmap_coherent(); else - kunmap_atomic(vaddr, KM_USER0); + kunmap_atomic(vaddr); } } diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 3634c7ea06a..aff57057a94 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -41,7 +41,7 @@ EXPORT_SYMBOL(kunmap); * kmaps are appropriate for short, tight code paths only. */ -void *__kmap_atomic(struct page *page) +void *kmap_atomic(struct page *page) { unsigned long vaddr; int idx, type; @@ -62,7 +62,7 @@ void *__kmap_atomic(struct page *page) return (void*) vaddr; } -EXPORT_SYMBOL(__kmap_atomic); +EXPORT_SYMBOL(kmap_atomic); void __kunmap_atomic(void *kvaddr) { diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 3b3ffd439cd..1a85ba92eb5 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -207,21 +207,21 @@ void copy_user_highpage(struct page *to, struct page *from, { void *vfrom, *vto; - vto = kmap_atomic(to, KM_USER1); + vto = kmap_atomic(to); if (cpu_has_dc_aliases && page_mapped(from) && !Page_dcache_dirty(from)) { vfrom = kmap_coherent(from, vaddr); copy_page(vto, vfrom); kunmap_coherent(); } else { - vfrom = kmap_atomic(from, KM_USER0); + vfrom = kmap_atomic(from); copy_page(vto, vfrom); - kunmap_atomic(vfrom, KM_USER0); + kunmap_atomic(vfrom); } if ((!cpu_has_ic_fills_f_dc) || pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) flush_data_cache_page((unsigned long)vto); - kunmap_atomic(vto, KM_USER1); + kunmap_atomic(vto); /* Make sure this page is cleared on other CPU's too before using it */ smp_wmb(); } diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c index 400535a955d..c682468010c 100644 --- a/arch/mips/pci/pci-bcm47xx.c +++ b/arch/mips/pci/pci-bcm47xx.c @@ -25,6 +25,7 @@ #include <linux/types.h> #include <linux/pci.h> #include <linux/ssb/ssb.h> +#include <linux/bcma/bcma.h> #include <bcm47xx.h> int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) @@ -32,15 +33,12 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return 0; } -int pcibios_plat_dev_init(struct pci_dev *dev) -{ #ifdef CONFIG_BCM47XX_SSB +static int bcm47xx_pcibios_plat_dev_init_ssb(struct pci_dev *dev) +{ int res; u8 slot, pin; - if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB) - return 0; - res = ssb_pcibios_plat_dev_init(dev); if (res < 0) { printk(KERN_ALERT "PCI: Failed to init device %s\n", @@ -60,6 +58,47 @@ int pcibios_plat_dev_init(struct pci_dev *dev) } dev->irq = res; + return 0; +} #endif + +#ifdef CONFIG_BCM47XX_BCMA +static int bcm47xx_pcibios_plat_dev_init_bcma(struct pci_dev *dev) +{ + int res; + + res = bcma_core_pci_plat_dev_init(dev); + if (res < 0) { + printk(KERN_ALERT "PCI: Failed to init device %s\n", + pci_name(dev)); + return res; + } + + res = bcma_core_pci_pcibios_map_irq(dev); + + /* IRQ-0 and IRQ-1 are software interrupts. */ + if (res < 2) { + printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n", + pci_name(dev)); + return res; + } + + dev->irq = res; return 0; } +#endif + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ +#ifdef CONFIG_BCM47XX_SSB + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_SSB) + return bcm47xx_pcibios_plat_dev_init_ssb(dev); + else +#endif +#ifdef CONFIG_BCM47XX_BCMA + if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) + return bcm47xx_pcibios_plat_dev_init_bcma(dev); + else +#endif + return 0; +} |