diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch b/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch new file mode 100644 index 0000000000..b3d13df39f --- /dev/null +++ b/target/linux/brcm47xx/patches-3.3/029-bcm47xx-read-nvram-from-sflash.patch @@ -0,0 +1,138 @@ +--- 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; +@@ -50,9 +51,6 @@ static void early_nvram_init(void) + #ifdef CONFIG_BCM47XX_BCMA + case BCM47XX_BUS_TYPE_BCMA: + bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc; +- if (bcma_cc->flash_type != BCMA_PFLASH) +- return; +- + base = bcma_cc->pflash.window; + lim = bcma_cc->pflash.window_size; + break; +@@ -86,7 +84,110 @@ 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; ++} ++ ++#ifdef CONFIG_BCM47XX_SSB ++static void early_nvram_init_ssb(void) ++{ ++ int err; ++ ++ switch (bcm47xx_bus.ssb.chipco.flash_type) { ++ case SSB_PFLASH: ++ early_nvram_init_pflash(); ++ break; ++ case SSB_SFLASH: ++ err = early_nvram_init_sflash(); ++ if (err < 0) ++ printk(KERN_WARNING "can not read from flash: %i\n", err); ++ break; ++ default: ++ printk(KERN_WARNING "unknow flash type\n"); ++ } ++} ++#endif ++ ++#ifdef CONFIG_BCM47XX_BCMA ++static void early_nvram_init_bcma(void) ++{ ++ int err; ++ ++ switch (bcm47xx_bus.bcma.bus.drv_cc.flash_type) { ++ case BCMA_PFLASH: ++ early_nvram_init_pflash(); ++ break; ++ case BCMA_SFLASH: ++ err = early_nvram_init_sflash(); ++ if (err < 0) ++ printk(KERN_WARNING "can not read from flash: %i\n", err); ++ break; ++ default: ++ printk(KERN_WARNING "unknow flash type\n"); ++ } ++} ++#endif ++ ++static void early_nvram_init(void) ++{ ++ switch (bcm47xx_bus_type) { ++#ifdef CONFIG_BCM47XX_SSB ++ case BCM47XX_BUS_TYPE_SSB: ++ early_nvram_init_ssb(); ++ break; ++#endif ++#ifdef CONFIG_BCM47XX_BCMA ++ case BCM47XX_BUS_TYPE_BCMA: ++ early_nvram_init_bcma(); ++ break; ++#endif ++ } + } + + int nvram_getenv(char *name, char *val, size_t val_len) |