diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/Kconfig | 1 | ||||
-rw-r--r-- | arch/mips/bcm47xx/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/bcm47xx/nvram.c | 246 |
3 files changed, 2 insertions, 247 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d53b43237f7f..dbb1a1d0f9b3 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -190,6 +190,7 @@ config BCM47XX select USE_GENERIC_EARLY_PRINTK_8250 select GPIOLIB select LEDS_GPIO_REGISTER + select BCM47XX_NVRAM help Support for BCM47XX based boards diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile index d58c51b5e501..66bea4ecf449 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/nvram.c b/arch/mips/bcm47xx/nvram.c deleted file mode 100644 index 9ccdce816f84..000000000000 --- a/arch/mips/bcm47xx/nvram.c +++ /dev/null @@ -1,246 +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 size_t nvram_len; -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_len) { - 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: - src = (u32 *)header; - dst = (u32 *)nvram_buf; - for (i = 0; i < sizeof(struct nvram_header); i += 4) - *dst++ = __raw_readl(src++); - header = (struct nvram_header *)nvram_buf; - nvram_len = header->len; - if (nvram_len > size) { - pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n"); - nvram_len = size; - } - if (nvram_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 - 1); - nvram_len = NVRAM_SPACE - 1; - } - /* proceed reading data after header */ - for (; i < nvram_len; i += 4) - *dst++ = readl(src++); - nvram_buf[NVRAM_SPACE - 1] = '\0'; - - 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 && - header.len > sizeof(header)) { - nvram_len = header.len; - if (nvram_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); - nvram_len = NVRAM_SPACE - 1; - } - - err = mtd_read(mtd, 0, nvram_len, &nvram_len, - (u8 *)nvram_buf); - return err; - } -#endif - - return -ENXIO; -} - -int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) -{ - char *var, *value, *end, *eq; - int err; - - if (!name) - return -EINVAL; - - if (!nvram_len) { - 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); - while (var < end && *var) { - eq = strchr(var, '='); - if (!eq) - break; - value = eq + 1; - if (eq - var == strlen(name) && - strncmp(var, name, eq - var) == 0) - return snprintf(val, val_len, "%s", value); - var = value + strlen(value) + 1; - } - 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); - -char *bcm47xx_nvram_get_contents(size_t *nvram_size) -{ - int err; - char *nvram; - - if (!nvram_len) { - err = nvram_init(); - if (err) - return NULL; - } - - *nvram_size = nvram_len - sizeof(struct nvram_header); - nvram = vmalloc(*nvram_size); - if (!nvram) - return NULL; - memcpy(nvram, &nvram_buf[sizeof(struct nvram_header)], *nvram_size); - - return nvram; -} -EXPORT_SYMBOL(bcm47xx_nvram_get_contents); |