From 1d693b2c9d5943cbe938f879041b837cd004737f Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens <hauke@hauke-m.de> Date: Sat, 23 Jul 2011 18:29:38 +0200 Subject: [PATCH 25/26] bcm47xx: read nvram from sflash bcm47xx: add sflash support to nvram Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> --- arch/mips/bcm47xx/nvram.c | 86 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 84 insertions(+), 2 deletions(-) --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c @@ -20,11 +20,12 @@ #include <asm/addrspace.h> #include <asm/mach-bcm47xx/nvram.h> #include <asm/mach-bcm47xx/bcm47xx.h> +#include <asm/mach-bcm47xx/bus.h> static char nvram_buf[NVRAM_SPACE]; /* Probe for NVRAM header */ -static void early_nvram_init(void) +static void early_nvram_init_pflash(void) { #ifdef CONFIG_BCM47XX_SSB struct ssb_chipcommon *ssb_cc; @@ -86,7 +87,88 @@ found: for (i = 0; i < sizeof(struct nvram_header); i += 4) *dst++ = *src++; for (; i < header->len && i < NVRAM_SPACE; i += 4) - *dst++ = le32_to_cpu(*src++); + *dst++ = *src++; +} + +static int early_nvram_init_sflash(void) +{ + struct nvram_header header; + u32 off; + int ret; + char *dst; + int len; + + /* check if the struct is already initilized */ + if (!bcm47xx_sflash.size) + return -1; + + off = FLASH_MIN; + while (off <= bcm47xx_sflash.size) { + ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - NVRAM_SPACE, sizeof(header), (u8 *)&header); + if (ret != sizeof(header)) + return ret; + if (header.magic == NVRAM_HEADER) + goto found; + off <<= 1; + } + + off = FLASH_MIN; + while (off <= bcm47xx_sflash.size) { + ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - (2 * NVRAM_SPACE), sizeof(header), (u8 *)&header); + if (ret != sizeof(header)) + return ret; + if (header.magic == NVRAM_HEADER) + goto found; + off <<= 1; + } + return -1; + +found: + len = NVRAM_SPACE; + dst = nvram_buf; + while (len) { + ret = bcm47xx_sflash.read(&bcm47xx_sflash, off - (2 * NVRAM_SPACE), len, dst); + if (ret < 0) + return ret; + off += ret; + len -= ret; + dst += ret; + } + return 0; +} + +static void early_nvram_init(void) +{ + int err = 0; + + switch (bcm47xx_bus_type) { +#ifdef CONFIG_BCM47XX_SSB + case BCM47XX_BUS_TYPE_SSB: + if (bcm47xx_bus.ssb.chipco.flash_type == SSB_PFLASH) { + early_nvram_init_pflash(); + } else if (bcm47xx_bus.ssb.chipco.flash_type == SSB_SFLASH) { + err = early_nvram_init_sflash(); + if (err < 0) + printk(KERN_WARNING "can not read from flash: %i\n", err); + } else { + printk(KERN_WARNING "unknow flash type\n"); + } + break; +#endif +#ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: + if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_PFLASH) { + early_nvram_init_pflash(); + } else if (bcm47xx_bus.bcma.bus.drv_cc.flash_type == BCMA_SFLASH) { + err = early_nvram_init_sflash(); + if (err < 0) + printk(KERN_WARNING "can not read from flash: %i\n", err); + } else { + printk(KERN_WARNING "unknow flash type\n"); + } + break; +#endif + } } int nvram_getenv(char *name, char *val, size_t val_len)