From: Rafał Miłecki <rafal@xxxxxxxxxx> Provide NVMEM content to the NVRAM driver from a simple memory resource. This is necessary to use NVRAM in a memory- mapped flash device. Patch taken from OpenWrts development tree. This patch makes it possible to use memory-mapped NVRAM on the D-Link DWL-8610AP and the D-Link DIR-890L. Cc: Hauke Mehrtens <hauke@xxxxxxxxxx> Cc: linux-mips@xxxxxxxxxxxxxxx Cc: Florian Fainelli <f.fainelli@xxxxxxxxx> Cc: bcm-kernel-feedback-list@xxxxxxxxxxxx Cc: Thomas Bogendoerfer <tsbogend@xxxxxxxxxxxxxxxx> Signed-off-by: Rafał Miłecki <rafal@xxxxxxxxxx> [Added an export for modules potentially using the init symbol] Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> --- This affects the ARM SoC in my case, but previous patches to this driver were merged through the MIPS tree so I expect Thomas to pick this up, if you prefer the SoC tree please tell me and I will resend. --- drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++ drivers/nvmem/brcm_nvram.c | 3 +++ include/linux/bcm47xx_nvram.h | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c index bd235833b687..5f47dbf4889a 100644 --- a/drivers/firmware/broadcom/bcm47xx_nvram.c +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c @@ -110,6 +110,24 @@ static int bcm47xx_nvram_find_and_copy(void __iomem *flash_start, size_t res_siz return 0; } +int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size) +{ + if (nvram_len) { + pr_warn("nvram already initialized\n"); + return -EEXIST; + } + + if (!bcm47xx_nvram_is_valid(nvram_start)) { + pr_err("No valid NVRAM found\n"); + return -ENOENT; + } + + bcm47xx_nvram_copy(nvram_start, res_size); + + return 0; +} +EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem); + /* * 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 diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c index 4441daa20965..34130449f2d2 100644 --- a/drivers/nvmem/brcm_nvram.c +++ b/drivers/nvmem/brcm_nvram.c @@ -3,6 +3,7 @@ * Copyright (C) 2021 Rafał Miłecki <rafal@xxxxxxxxxx> */ +#include <linux/bcm47xx_nvram.h> #include <linux/io.h> #include <linux/mod_devicetable.h> #include <linux/module.h> @@ -136,6 +137,8 @@ static int brcm_nvram_probe(struct platform_device *pdev) if (err) return err; + bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); + config.dev = dev; config.cells = priv->cells; config.ncells = priv->ncells; diff --git a/include/linux/bcm47xx_nvram.h b/include/linux/bcm47xx_nvram.h index 53b31f69b74a..7615f8d7b1ed 100644 --- a/include/linux/bcm47xx_nvram.h +++ b/include/linux/bcm47xx_nvram.h @@ -11,6 +11,7 @@ #include <linux/vmalloc.h> #ifdef CONFIG_BCM47XX_NVRAM +int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size); int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); int bcm47xx_nvram_gpio_pin(const char *name); @@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release_contents(char *nvram) vfree(nvram); }; #else +static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, + size_t res_size) +{ + return -ENOTSUPP; +} static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) { return -ENOTSUPP; -- 2.34.1