bcm53xx: add support for reading NVRAM based on DT mapping

This is required for devices that use NVRAM data for detecting currently
used firmware partition (e.g. Linksys devices).

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2021-03-02 09:04:48 +01:00
parent e3ab355dde
commit b0376462c1
2 changed files with 141 additions and 0 deletions

View File

@ -0,0 +1,56 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 2 Mar 2021 08:23:35 +0100
Subject: [PATCH] dt-bindings: firmware: add Broadcom's NVRAM memory mapping
NVRAM structure contains device data and can be accessed using MMIO.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../bindings/firmware/brcm,nvram.yaml | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/firmware/brcm,nvram.yaml
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/brcm,nvram.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/firmware/brcm,nvram.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Broadcom's NVRAM
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+description: |
+ NVRAM is a structure containing device specific environment variables.
+ It is used for storing device configuration, booting parameters and
+ calibration data.
+
+ It's required very early in booting process and so is made available
+ using memory mapping.
+
+ NVRAM can be found on Broadcom BCM47xx MIPS, Northstar ARM Cortex-A9
+ and some more devices.
+
+properties:
+ compatible:
+ const: brcm,nvram
+
+ reg:
+ description: memory region with NVRAM data
+ maxItems: 1
+
+required:
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ nvram@1e000000 {
+ compatible = "brcm,nvram";
+ reg = <0x1e000000 0x10000>;
+ };

View File

@ -0,0 +1,85 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 2 Mar 2021 08:33:13 +0100
Subject: [PATCH] firmware: bcm47xx_nvram: support platform device "brcm,nvram"
Add support for platform device providing mapping resource. This allows
reading NVRAM based on DT mapping binding. It's required for devices
that boot depending on NVRAM stored setup and provides early access to
NVRAM data.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
drivers/firmware/broadcom/bcm47xx_nvram.c | 55 +++++++++++++++++++++++
1 file changed, 55 insertions(+)
--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/mtd/mtd.h>
+#include <linux/platform_device.h>
#include <linux/bcm47xx_nvram.h>
#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
@@ -162,6 +163,60 @@ static int nvram_init(void)
return -ENXIO;
}
+static int brcm_nvram_probe(struct platform_device *pdev)
+{
+ struct nvram_header __iomem *header;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ void __iomem *mmio;
+ size_t copy_len;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Failed to get resource\n");
+ return -ENODEV;
+ }
+
+ mmio = ioremap(res->start, resource_size(res));
+ if (!mmio)
+ return -ENOMEM;
+
+ header = (struct nvram_header *)mmio;
+ copy_len = DIV_ROUND_UP(sizeof(*header) + header->len, 4);
+ if (header->magic != NVRAM_MAGIC) {
+ dev_err(dev, "No NVRAM found at %pR\n", res);
+ return -EPROTO;
+ } else if (copy_len > resource_size(res)) {
+ dev_err(dev, "NVRAM size exceeds %pR\n", res);
+ return -ERANGE;
+ } else if (copy_len >= NVRAM_SPACE) {
+ dev_err(dev, "NVRAM size exceeds buffer size %d\n", NVRAM_SPACE);
+ return -ENOMEM;
+ }
+
+ __ioread32_copy(nvram_buf, mmio, copy_len);
+ nvram_buf[NVRAM_SPACE - 1] = '\0';
+
+ iounmap(mmio);
+
+ return 0;
+}
+
+static const struct of_device_id brcm_nvram_of_match[] = {
+ { .compatible = "brcm,nvram "},
+ {},
+};
+
+static struct platform_driver brcm_nvram_driver = {
+ .driver = {
+ .name = "brcm_nvram",
+ .of_match_table = brcm_nvram_of_match,
+ },
+ .probe = brcm_nvram_probe,
+};
+
+module_platform_driver(brcm_nvram_driver);
+
int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
{
char *var, *value, *end, *eq;