Commit a5be5ce0 authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Florian Fainelli
Browse files

firmware/nvram: bcm47xx: support init from IO memory



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@hauke-m.de>
Cc: linux-mips@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: bcm-kernel-feedback-list@broadcom.com
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: default avatarRafał Miłecki <rafal@milecki.pl>
[Added an export for modules potentially using the init symbol]
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org


Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
parent 117bd98d
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
 */

#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;
+6 −0
Original line number Diff line number Diff line
@@ -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;