diff options
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r-- | arch/mips/bcm47xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/bcm47xx/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/bcm47xx/board.c | 1 | ||||
-rw-r--r-- | arch/mips/bcm47xx/buttons.c | 11 | ||||
-rw-r--r-- | arch/mips/bcm47xx/leds.c | 14 | ||||
-rw-r--r-- | arch/mips/bcm47xx/nvram.c | 223 | ||||
-rw-r--r-- | arch/mips/bcm47xx/prom.c | 2 | ||||
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 3 | ||||
-rw-r--r-- | arch/mips/bcm47xx/sprom.c | 106 |
9 files changed, 68 insertions, 295 deletions
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index fc21d3659..51ed599cc 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -25,7 +25,6 @@ config BCM47XX_BCMA select BCMA select BCMA_HOST_SOC select BCMA_DRIVER_MIPS - select BCMA_HOST_PCI if PCI select BCMA_DRIVER_PCI_HOSTMODE if PCI select BCMA_DRIVER_GPIO default y diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index d58c51b5e..66bea4ecf 100644 --- a/arch/mips/bcm47xx/Makefile +++ b/arch/mips/bcm47xx/Makefile @@ -3,5 +3,5 @@ # under Linux. # -obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o +obj-y += irq.o prom.o serial.o setup.o time.o sprom.o obj-y += board.o buttons.o leds.o workarounds.o diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index bd56415f2..a88975a55 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -149,6 +149,7 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = { /* board_id */ static const struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = { + {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"}, {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"}, diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 276276a8c..08a4abf09 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c @@ -299,6 +299,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { BCM47XX_GPIO_KEY(6, KEY_RESTART), }; +/* Luxul */ + +static const struct gpio_keys_button +bcm47xx_buttons_luxul_xwr_1750_v1[] = { + BCM47XX_GPIO_KEY(14, BTN_TASK), +}; + /* Microsoft */ static const struct gpio_keys_button @@ -555,6 +562,10 @@ int __init bcm47xx_buttons_register(void) err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); break; + case BCM47XX_BOARD_LUXUL_XWR_1750_V1: + err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xwr_1750_v1); + break; + case BCM47XX_BOARD_MICROSOFT_MN700: err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700); break; diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c index 0e4ade342..d20ae63eb 100644 --- a/arch/mips/bcm47xx/leds.c +++ b/arch/mips/bcm47xx/leds.c @@ -370,6 +370,16 @@ bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), }; +/* Luxul */ + +static const struct gpio_led +bcm47xx_leds_luxul_xwr_1750_v1[] __initconst = { + BCM47XX_GPIO_LED(5, "green", "5ghz", 0, LEDS_GPIO_DEFSTATE_OFF), + BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), + BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 0, "timer"), + BCM47XX_GPIO_LED(15, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), +}; + /* Microsoft */ static const struct gpio_led @@ -623,6 +633,10 @@ void __init bcm47xx_leds_register(void) bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); break; + case BCM47XX_BOARD_LUXUL_XWR_1750_V1: + bcm47xx_set_pdata(bcm47xx_leds_luxul_xwr_1750_v1); + break; + case BCM47XX_BOARD_MICROSOFT_MN700: bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700); break; diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c deleted file mode 100644 index ba632ff08..000000000 --- a/arch/mips/bcm47xx/nvram.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * BCM947xx nvram variable access - * - * Copyright (C) 2005 Broadcom Corporation - * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.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. - */ - -#include <linux/io.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/mtd/mtd.h> -#include <linux/bcm47xx_nvram.h> - -#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ -#define NVRAM_SPACE 0x10000 -#define NVRAM_MAX_GPIO_ENTRIES 32 -#define NVRAM_MAX_GPIO_VALUE_LEN 30 - -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -struct nvram_header { - u32 magic; - u32 len; - u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ - u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ - u32 config_ncdl; /* ncdl values for memc */ -}; - -static char nvram_buf[NVRAM_SPACE]; -static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; - -static u32 find_nvram_size(void __iomem *end) -{ - struct nvram_header __iomem *header; - int i; - - for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { - header = (struct nvram_header *)(end - nvram_sizes[i]); - if (header->magic == NVRAM_MAGIC) - return nvram_sizes[i]; - } - - return 0; -} - -/* Probe for NVRAM header */ -static int nvram_find_and_copy(void __iomem *iobase, u32 lim) -{ - 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(iobase + off); - if (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 *)(iobase + 4096); - if (header->magic == NVRAM_MAGIC) { - size = NVRAM_SPACE; - goto found; - } - - header = (struct nvram_header *)(iobase + 1024); - if (header->magic == NVRAM_MAGIC) { - size = NVRAM_SPACE; - goto found; - } - - pr_err("no nvram found\n"); - return -ENXIO; - -found: - if (header->len > size) - pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n"); - if (header->len > NVRAM_SPACE) - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", - header->len, NVRAM_SPACE); - - src = (u32 *)header; - dst = (u32 *)nvram_buf; - for (i = 0; i < sizeof(struct nvram_header); i += 4) - *dst++ = __raw_readl(src++); - for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4) - *dst++ = readl(src++); - - return 0; -} - -/* - * 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; - - iobase = ioremap_nocache(base, lim); - if (!iobase) - return -ENOMEM; - - err = nvram_find_and_copy(iobase, lim); - - iounmap(iobase); - - return err; -} - -static int nvram_init(void) -{ -#ifdef CONFIG_MTD - struct mtd_info *mtd; - struct nvram_header header; - size_t bytes_read; - int err; - - mtd = get_mtd_device_nm("nvram"); - if (IS_ERR(mtd)) - return -ENODEV; - - err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header); - if (!err && header.magic == NVRAM_MAGIC) { - u8 *dst = (uint8_t *)nvram_buf; - size_t len = header.len; - - if (header.len > NVRAM_SPACE) { - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", - header.len, NVRAM_SPACE); - len = NVRAM_SPACE; - } - - err = mtd_read(mtd, 0, len, &bytes_read, dst); - if (err) - return err; - - return 0; - } -#endif - - return -ENXIO; -} - -int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) -{ - char *var, *value, *end, *eq; - int data_left, err; - - if (!name) - return -EINVAL; - - if (!nvram_buf[0]) { - err = nvram_init(); - if (err) - return err; - } - - /* Look for name=value and return value */ - var = &nvram_buf[sizeof(struct nvram_header)]; - end = nvram_buf + sizeof(nvram_buf) - 2; - end[0] = '\0'; - end[1] = '\0'; - for (; *var; var = value + strlen(value) + 1) { - data_left = end - var; - - eq = strnchr(var, data_left, '='); - if (!eq) - break; - value = eq + 1; - if (eq - var == strlen(name) && - strncmp(var, name, eq - var) == 0) - return snprintf(val, val_len, "%s", value); - } - return -ENOENT; -} -EXPORT_SYMBOL(bcm47xx_nvram_getenv); - -int bcm47xx_nvram_gpio_pin(const char *name) -{ - int i, err; - char nvram_var[] = "gpioXX"; - char buf[NVRAM_MAX_GPIO_VALUE_LEN]; - - /* TODO: Optimize it to don't call getenv so many times */ - for (i = 0; i < NVRAM_MAX_GPIO_ENTRIES; i++) { - err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i); - if (err <= 0) - continue; - err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf)); - if (err <= 0) - continue; - if (!strcmp(name, buf)) - return i; - } - return -ENOENT; -} -EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin); diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index ab698bad6..135a5407f 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c @@ -126,7 +126,7 @@ void __init prom_free_prom_memory(void) /* Stripped version of tlb_init, with the call to build_tlb_refill_handler * dropped. Calling it at this stage causes a hang. */ -void __cpuinit early_tlb_init(void) +void early_tlb_init(void) { write_c0_pagemask(PM_DEFAULT_MASK); write_c0_wired(0); diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 82ff9fd2a..98c075f81 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -206,9 +206,6 @@ void __init bcm47xx_bus_setup(void) 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 diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index 68ebf2322..2d5c7a7f2 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -200,7 +200,13 @@ static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom, const char *pre = prefix; bool fb = fallback; + /* Broadcom extracts it for rev 8+ but it was found on 2 and 4 too */ + ENTRY(0xfffffffe, u16, pre, "devid", dev_id, 0, fallback); + ENTRY(0xfffffffe, u16, pre, "boardrev", board_rev, 0, true); + ENTRY(0xfffffffe, u32, pre, "boardflags", boardflags, 0, fb); + ENTRY(0xfffffff0, u32, pre, "boardflags2", boardflags2, 0, fb); + ENTRY(0xfffff800, u32, pre, "boardflags3", boardflags3, 0, fb); ENTRY(0x00000002, u16, pre, "boardflags", boardflags_lo, 0, fb); ENTRY(0xfffffffc, u16, pre, "boardtype", board_type, 0, true); ENTRY(0xfffffffe, u16, pre, "boardnum", board_num, 0, fb); @@ -409,27 +415,6 @@ static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom, } #undef ENTRY /* It's specififc, uses local variable, don't use it (again). */ -static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, - const char *prefix, bool fallback) -{ - nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback); - nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback); -} - -static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix, - bool fallback) -{ - nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, - &sprom->leddc_off_time, fallback); -} - -static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom, - const char *prefix, bool fallback) -{ - nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, - &sprom->leddc_off_time, fallback); -} - static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom, const char *prefix, bool fallback) { @@ -528,6 +513,8 @@ static int mac_addr_used = 2; static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, const char *prefix, bool fallback) { + bool fb = fallback; + nvram_read_macaddr(prefix, "et0macaddr", sprom->et0mac, fallback); nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0, fallback); @@ -540,6 +527,10 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0, fallback); + nvram_read_macaddr(prefix, "et2macaddr", sprom->et2mac, fb); + nvram_read_u8(prefix, NULL, "et2mdcport", &sprom->et2mdcport, 0, fb); + nvram_read_u8(prefix, NULL, "et2phyaddr", &sprom->et2phyaddr, 0, fb); + nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback); nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback); @@ -580,39 +571,22 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback); + /* Entries requiring custom functions */ + nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback); + if (sprom->revision >= 3) + nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time, + &sprom->leddc_off_time, fallback); + switch (sprom->revision) { - case 1: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - break; - case 2: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - break; - case 3: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - bcm47xx_fill_sprom_r3(sprom, prefix, fallback); - break; case 4: case 5: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback); break; case 8: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); - bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); - break; case 9: - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); - bcm47xx_fill_sprom_r4589(sprom, prefix, fallback); bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback); break; - default: - pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n", - sprom->revision); - sprom->revision = 1; - bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback); } bcm47xx_sprom_fill_auto(sprom, prefix, fallback); @@ -631,19 +605,6 @@ void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, } #endif -#ifdef CONFIG_BCM47XX_BCMA -void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, - const char *prefix) -{ - nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0, - true); - if (!boardinfo->vendor) - boardinfo->vendor = SSB_BOARDVENDOR_BCM; - - 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) { @@ -698,33 +659,46 @@ static void bcm47xx_sprom_apply_prefix_alias(char *prefix, size_t prefix_size) static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) { - char prefix[10]; + struct bcma_boardinfo *binfo = &bus->boardinfo; struct bcma_device *core; + char buf[10]; + char *prefix; + bool fallback = false; switch (bus->hosttype) { case BCMA_HOSTTYPE_PCI: memset(out, 0, sizeof(struct ssb_sprom)); - snprintf(prefix, sizeof(prefix), "pci/%u/%u/", + snprintf(buf, sizeof(buf), "pci/%u/%u/", bus->host_pci->bus->number + 1, PCI_SLOT(bus->host_pci->devfn)); - bcm47xx_sprom_apply_prefix_alias(prefix, sizeof(prefix)); - bcm47xx_fill_sprom(out, prefix, false); - return 0; + bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf)); + prefix = buf; + break; 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/", + snprintf(buf, sizeof(buf), "sb/%u/", core->core_index); - bcm47xx_fill_sprom(out, prefix, true); + prefix = buf; + fallback = true; } else { - bcm47xx_fill_sprom(out, NULL, false); + prefix = NULL; } - return 0; + break; default: pr_warn("Unable to fill SPROM for given bustype.\n"); return -EINVAL; } + + nvram_read_u16(prefix, NULL, "boardvendor", &binfo->vendor, 0, true); + if (!binfo->vendor) + binfo->vendor = SSB_BOARDVENDOR_BCM; + nvram_read_u16(prefix, NULL, "boardtype", &binfo->type, 0, true); + + bcm47xx_fill_sprom(out, prefix, fallback); + + return 0; } #endif |