mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-20 17:32:57 +00:00
kernel: backport nvmem changes from v6.12
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
c7ba5574f5
commit
e39ae96f88
@ -27,7 +27,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/drivers/nvmem/layouts.c
|
||||
+++ b/drivers/nvmem/layouts.c
|
||||
@@ -52,13 +52,15 @@ static const struct bus_type nvmem_layou
|
||||
@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_
|
||||
.remove = nvmem_layout_bus_remove,
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
|
||||
From: Peng Fan <peng.fan@nxp.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:45 +0100
|
||||
Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
|
||||
|
||||
i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
|
||||
some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
|
||||
|
||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
|
||||
1 file changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp-ele.c
|
||||
+++ b/drivers/nvmem/imx-ocotp-ele.c
|
||||
@@ -14,8 +14,9 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
enum fuse_type {
|
||||
- FUSE_FSB = 1,
|
||||
- FUSE_ELE = 2,
|
||||
+ FUSE_FSB = BIT(0),
|
||||
+ FUSE_ELE = BIT(1),
|
||||
+ FUSE_ECC = BIT(2),
|
||||
FUSE_INVALID = -1
|
||||
};
|
||||
|
||||
@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
|
||||
continue;
|
||||
}
|
||||
|
||||
- *buf++ = readl_relaxed(reg + (i << 2));
|
||||
+ if (type & FUSE_ECC)
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
|
||||
+ else
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2));
|
||||
}
|
||||
|
||||
memcpy(val, (u8 *)p, bytes);
|
||||
@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct ocotp_devtype_data imx95_ocotp_data = {
|
||||
+ .reg_off = 0x8000,
|
||||
+ .reg_read = imx_ocotp_reg_read,
|
||||
+ .size = 2048,
|
||||
+ .num_entry = 12,
|
||||
+ .entry = {
|
||||
+ { 0, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 7, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 9, 3, FUSE_FSB | FUSE_ECC },
|
||||
+ { 12, 24, FUSE_FSB },
|
||||
+ { 36, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 38, 14, FUSE_FSB },
|
||||
+ { 63, 1, FUSE_ELE },
|
||||
+ { 128, 16, FUSE_ELE },
|
||||
+ { 188, 1, FUSE_ELE },
|
||||
+ { 317, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 320, 7, FUSE_FSB },
|
||||
+ { 328, 184, FUSE_FSB }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
|
||||
+ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
|
@ -0,0 +1,44 @@
|
||||
From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:50 +0100
|
||||
Subject: [PATCH] nvmem: sunplus-ocotp: Use
|
||||
devm_platform_ioremap_resource_byname() helper function
|
||||
|
||||
platform_get_resource_byname() and devm_ioremap_resource() can be
|
||||
replaced by devm_platform_ioremap_resource_byname(), which can
|
||||
simplify the code logic a bit, No functional change here.
|
||||
|
||||
Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/sunplus-ocotp.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/sunplus-ocotp.c
|
||||
+++ b/drivers/nvmem/sunplus-ocotp.c
|
||||
@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
|
||||
struct device *dev = &pdev->dev;
|
||||
struct nvmem_device *nvmem;
|
||||
struct sp_ocotp_priv *otp;
|
||||
- struct resource *res;
|
||||
int ret;
|
||||
|
||||
otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
|
||||
@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
|
||||
|
||||
otp->dev = dev;
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
|
||||
- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
|
||||
if (IS_ERR(otp->base[HB_GPIO]))
|
||||
return PTR_ERR(otp->base[HB_GPIO]);
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
|
||||
- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
|
||||
if (IS_ERR(otp->base[OTPRX]))
|
||||
return PTR_ERR(otp->base[OTPRX]);
|
||||
|
@ -0,0 +1,515 @@
|
||||
From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Mon, 2 Sep 2024 15:29:47 +0100
|
||||
Subject: [PATCH] nvmem: layouts: add U-Boot env layout
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
U-Boot environment variables are stored in a specific format. Actual
|
||||
data can be placed in various storage sources (MTD, UBI volume, EEPROM,
|
||||
NVRAM, etc.).
|
||||
|
||||
Move all generic (NVMEM device independent) code from NVMEM device
|
||||
driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
|
||||
top of it.
|
||||
|
||||
This allows using NVMEM layout for parsing U-Boot env data stored in any
|
||||
kind of NVMEM device.
|
||||
|
||||
The old NVMEM glue driver stays in place for handling bindings in the
|
||||
MTD context. To avoid code duplication it uses exported layout parsing
|
||||
function. Please note that handling MTD & NVMEM layout bindings may be
|
||||
refactored in the future.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/nvmem/Kconfig | 3 +-
|
||||
drivers/nvmem/layouts/Kconfig | 11 ++
|
||||
drivers/nvmem/layouts/Makefile | 1 +
|
||||
drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
|
||||
drivers/nvmem/layouts/u-boot-env.h | 15 ++
|
||||
drivers/nvmem/u-boot-env.c | 165 +---------------------
|
||||
7 files changed, 242 insertions(+), 165 deletions(-)
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.c
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.h
|
||||
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
|
||||
config NVMEM_U_BOOT_ENV
|
||||
tristate "U-Boot environment variables support"
|
||||
depends on OF && MTD
|
||||
- select CRC32
|
||||
- select GENERIC_NET_UTILS
|
||||
+ select NVMEM_LAYOUT_U_BOOT_ENV
|
||||
help
|
||||
U-Boot stores its setup as environment variables. This driver adds
|
||||
support for verifying & exporting such data. It also exposes variables
|
||||
--- a/drivers/nvmem/layouts/Kconfig
|
||||
+++ b/drivers/nvmem/layouts/Kconfig
|
||||
@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config NVMEM_LAYOUT_U_BOOT_ENV
|
||||
+ tristate "U-Boot environment variables layout"
|
||||
+ select CRC32
|
||||
+ select GENERIC_NET_UTILS
|
||||
+ help
|
||||
+ U-Boot stores its setup as environment variables. This driver adds
|
||||
+ support for verifying & exporting such data. It also exposes variables
|
||||
+ as NVMEM cells so they can be referenced by other drivers.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/drivers/nvmem/layouts/Makefile
|
||||
+++ b/drivers/nvmem/layouts/Makefile
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
|
||||
+obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -0,0 +1,211 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/crc32.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/if_ether.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/nvmem-provider.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include "u-boot-env.h"
|
||||
+
|
||||
+struct u_boot_env_image_single {
|
||||
+ __le32 crc32;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_redundant {
|
||||
+ __le32 crc32;
|
||||
+ u8 mark;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_broadcom {
|
||||
+ __le32 magic;
|
||||
+ __le32 len;
|
||||
+ __le32 crc32;
|
||||
+ DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
+} __packed;
|
||||
+
|
||||
+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
+ unsigned int offset, void *buf, size_t bytes)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (bytes != 3 * ETH_ALEN - 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (index)
|
||||
+ eth_addr_add(mac, index);
|
||||
+
|
||||
+ ether_addr_copy(buf, mac);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
|
||||
+ size_t data_offset, size_t data_len)
|
||||
+{
|
||||
+ char *data = buf + data_offset;
|
||||
+ char *var, *value, *eq;
|
||||
+
|
||||
+ for (var = data;
|
||||
+ var < data + data_len && *var;
|
||||
+ var = value + strlen(value) + 1) {
|
||||
+ struct nvmem_cell_info info = {};
|
||||
+
|
||||
+ eq = strchr(var, '=');
|
||||
+ if (!eq)
|
||||
+ break;
|
||||
+ *eq = '\0';
|
||||
+ value = eq + 1;
|
||||
+
|
||||
+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
+ if (!info.name)
|
||||
+ return -ENOMEM;
|
||||
+ info.offset = data_offset + value - data;
|
||||
+ info.bytes = strlen(value);
|
||||
+ info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
+ if (!strcmp(var, "ethaddr")) {
|
||||
+ info.raw_len = strlen(value);
|
||||
+ info.bytes = ETH_ALEN;
|
||||
+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
+ }
|
||||
+
|
||||
+ nvmem_add_one_cell(nvmem, &info);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format)
|
||||
+{
|
||||
+ size_t crc32_data_offset;
|
||||
+ size_t crc32_data_len;
|
||||
+ size_t crc32_offset;
|
||||
+ __le32 *crc32_addr;
|
||||
+ size_t data_offset;
|
||||
+ size_t data_len;
|
||||
+ size_t dev_size;
|
||||
+ uint32_t crc32;
|
||||
+ uint32_t calc;
|
||||
+ uint8_t *buf;
|
||||
+ int bytes;
|
||||
+ int err;
|
||||
+
|
||||
+ dev_size = nvmem_dev_size(nvmem);
|
||||
+
|
||||
+ buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
+ if (!buf) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
+ if (bytes < 0) {
|
||||
+ err = bytes;
|
||||
+ goto err_kfree;
|
||||
+ } else if (bytes != dev_size) {
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ switch (format) {
|
||||
+ case U_BOOT_FORMAT_SINGLE:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_REDUNDANT:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_BROADCOM:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev_size < data_offset) {
|
||||
+ dev_err(dev, "Device too small for u-boot-env\n");
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
+ crc32 = le32_to_cpu(*crc32_addr);
|
||||
+ crc32_data_len = dev_size - crc32_data_offset;
|
||||
+ data_len = dev_size - data_offset;
|
||||
+
|
||||
+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
+ if (calc != crc32) {
|
||||
+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
+ err = -EINVAL;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ buf[dev_size - 1] = '\0';
|
||||
+ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
|
||||
+
|
||||
+err_kfree:
|
||||
+ kfree(buf);
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(u_boot_env_parse);
|
||||
+
|
||||
+static int u_boot_env_add_cells(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ struct device *dev = &layout->dev;
|
||||
+ enum u_boot_env_format format;
|
||||
+
|
||||
+ format = (uintptr_t)device_get_match_data(dev);
|
||||
+
|
||||
+ return u_boot_env_parse(dev, layout->nvmem, format);
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_probe(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ layout->add_cells = u_boot_env_add_cells;
|
||||
+
|
||||
+ return nvmem_layout_register(layout);
|
||||
+}
|
||||
+
|
||||
+static void u_boot_env_remove(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ nvmem_layout_unregister(layout);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id u_boot_env_of_match_table[] = {
|
||||
+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
|
||||
+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static struct nvmem_layout_driver u_boot_env_layout = {
|
||||
+ .driver = {
|
||||
+ .name = "u-boot-env-layout",
|
||||
+ .of_match_table = u_boot_env_of_match_table,
|
||||
+ },
|
||||
+ .probe = u_boot_env_probe,
|
||||
+ .remove = u_boot_env_remove,
|
||||
+};
|
||||
+module_nvmem_layout_driver(u_boot_env_layout);
|
||||
+
|
||||
+MODULE_AUTHOR("Rafał Miłecki");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
|
||||
+MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+
|
||||
+#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+
|
||||
+enum u_boot_env_format {
|
||||
+ U_BOOT_FORMAT_SINGLE,
|
||||
+ U_BOOT_FORMAT_REDUNDANT,
|
||||
+ U_BOOT_FORMAT_BROADCOM,
|
||||
+};
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format);
|
||||
+
|
||||
+#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -3,23 +3,15 @@
|
||||
* Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
|
||||
*/
|
||||
|
||||
-#include <linux/crc32.h>
|
||||
-#include <linux/etherdevice.h>
|
||||
-#include <linux/if_ether.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
-#include <linux/nvmem-consumer.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
-enum u_boot_env_format {
|
||||
- U_BOOT_FORMAT_SINGLE,
|
||||
- U_BOOT_FORMAT_REDUNDANT,
|
||||
- U_BOOT_FORMAT_BROADCOM,
|
||||
-};
|
||||
+#include "layouts/u-boot-env.h"
|
||||
|
||||
struct u_boot_env {
|
||||
struct device *dev;
|
||||
@@ -29,24 +21,6 @@ struct u_boot_env {
|
||||
struct mtd_info *mtd;
|
||||
};
|
||||
|
||||
-struct u_boot_env_image_single {
|
||||
- __le32 crc32;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_redundant {
|
||||
- __le32 crc32;
|
||||
- u8 mark;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_broadcom {
|
||||
- __le32 magic;
|
||||
- __le32 len;
|
||||
- __le32 crc32;
|
||||
- DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
-} __packed;
|
||||
-
|
||||
static int u_boot_env_read(void *context, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
- unsigned int offset, void *buf, size_t bytes)
|
||||
-{
|
||||
- u8 mac[ETH_ALEN];
|
||||
-
|
||||
- if (bytes != 3 * ETH_ALEN - 1)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (!mac_pton(buf, mac))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (index)
|
||||
- eth_addr_add(mac, index);
|
||||
-
|
||||
- ether_addr_copy(buf, mac);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
|
||||
- size_t data_offset, size_t data_len)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- char *data = buf + data_offset;
|
||||
- char *var, *value, *eq;
|
||||
-
|
||||
- for (var = data;
|
||||
- var < data + data_len && *var;
|
||||
- var = value + strlen(value) + 1) {
|
||||
- struct nvmem_cell_info info = {};
|
||||
-
|
||||
- eq = strchr(var, '=');
|
||||
- if (!eq)
|
||||
- break;
|
||||
- *eq = '\0';
|
||||
- value = eq + 1;
|
||||
-
|
||||
- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
- if (!info.name)
|
||||
- return -ENOMEM;
|
||||
- info.offset = data_offset + value - data;
|
||||
- info.bytes = strlen(value);
|
||||
- info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
- if (!strcmp(var, "ethaddr")) {
|
||||
- info.raw_len = strlen(value);
|
||||
- info.bytes = ETH_ALEN;
|
||||
- info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
- }
|
||||
-
|
||||
- nvmem_add_one_cell(nvmem, &info);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_parse(struct u_boot_env *priv)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- size_t crc32_data_offset;
|
||||
- size_t crc32_data_len;
|
||||
- size_t crc32_offset;
|
||||
- __le32 *crc32_addr;
|
||||
- size_t data_offset;
|
||||
- size_t data_len;
|
||||
- size_t dev_size;
|
||||
- uint32_t crc32;
|
||||
- uint32_t calc;
|
||||
- uint8_t *buf;
|
||||
- int bytes;
|
||||
- int err;
|
||||
-
|
||||
- dev_size = nvmem_dev_size(nvmem);
|
||||
-
|
||||
- buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
- if (!buf) {
|
||||
- err = -ENOMEM;
|
||||
- goto err_out;
|
||||
- }
|
||||
-
|
||||
- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
- if (bytes < 0) {
|
||||
- err = bytes;
|
||||
- goto err_kfree;
|
||||
- } else if (bytes != dev_size) {
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- switch (priv->format) {
|
||||
- case U_BOOT_FORMAT_SINGLE:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_REDUNDANT:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_BROADCOM:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (dev_size < data_offset) {
|
||||
- dev_err(dev, "Device too small for u-boot-env\n");
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
- crc32 = le32_to_cpu(*crc32_addr);
|
||||
- crc32_data_len = dev_size - crc32_data_offset;
|
||||
- data_len = dev_size - data_offset;
|
||||
-
|
||||
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
- if (calc != crc32) {
|
||||
- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
- err = -EINVAL;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- buf[dev_size - 1] = '\0';
|
||||
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
|
||||
-
|
||||
-err_kfree:
|
||||
- kfree(buf);
|
||||
-err_out:
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static int u_boot_env_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct nvmem_config config = {
|
||||
@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
|
||||
if (IS_ERR(priv->nvmem))
|
||||
return PTR_ERR(priv->nvmem);
|
||||
|
||||
- return u_boot_env_parse(priv);
|
||||
+ return u_boot_env_parse(dev, priv->nvmem, priv->format);
|
||||
}
|
||||
|
||||
static const struct of_device_id u_boot_env_of_match_table[] = {
|
@ -27,7 +27,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
--- a/drivers/nvmem/layouts.c
|
||||
+++ b/drivers/nvmem/layouts.c
|
||||
@@ -52,13 +52,15 @@ static const struct bus_type nvmem_layou
|
||||
@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_
|
||||
.remove = nvmem_layout_bus_remove,
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
|
||||
From: Peng Fan <peng.fan@nxp.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:45 +0100
|
||||
Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
|
||||
|
||||
i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
|
||||
some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
|
||||
|
||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
|
||||
1 file changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp-ele.c
|
||||
+++ b/drivers/nvmem/imx-ocotp-ele.c
|
||||
@@ -14,8 +14,9 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
enum fuse_type {
|
||||
- FUSE_FSB = 1,
|
||||
- FUSE_ELE = 2,
|
||||
+ FUSE_FSB = BIT(0),
|
||||
+ FUSE_ELE = BIT(1),
|
||||
+ FUSE_ECC = BIT(2),
|
||||
FUSE_INVALID = -1
|
||||
};
|
||||
|
||||
@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
|
||||
continue;
|
||||
}
|
||||
|
||||
- *buf++ = readl_relaxed(reg + (i << 2));
|
||||
+ if (type & FUSE_ECC)
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
|
||||
+ else
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2));
|
||||
}
|
||||
|
||||
memcpy(val, (u8 *)p, bytes);
|
||||
@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct ocotp_devtype_data imx95_ocotp_data = {
|
||||
+ .reg_off = 0x8000,
|
||||
+ .reg_read = imx_ocotp_reg_read,
|
||||
+ .size = 2048,
|
||||
+ .num_entry = 12,
|
||||
+ .entry = {
|
||||
+ { 0, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 7, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 9, 3, FUSE_FSB | FUSE_ECC },
|
||||
+ { 12, 24, FUSE_FSB },
|
||||
+ { 36, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 38, 14, FUSE_FSB },
|
||||
+ { 63, 1, FUSE_ELE },
|
||||
+ { 128, 16, FUSE_ELE },
|
||||
+ { 188, 1, FUSE_ELE },
|
||||
+ { 317, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 320, 7, FUSE_FSB },
|
||||
+ { 328, 184, FUSE_FSB }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
|
||||
+ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
|
@ -0,0 +1,44 @@
|
||||
From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:50 +0100
|
||||
Subject: [PATCH] nvmem: sunplus-ocotp: Use
|
||||
devm_platform_ioremap_resource_byname() helper function
|
||||
|
||||
platform_get_resource_byname() and devm_ioremap_resource() can be
|
||||
replaced by devm_platform_ioremap_resource_byname(), which can
|
||||
simplify the code logic a bit, No functional change here.
|
||||
|
||||
Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/sunplus-ocotp.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/sunplus-ocotp.c
|
||||
+++ b/drivers/nvmem/sunplus-ocotp.c
|
||||
@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
|
||||
struct device *dev = &pdev->dev;
|
||||
struct nvmem_device *nvmem;
|
||||
struct sp_ocotp_priv *otp;
|
||||
- struct resource *res;
|
||||
int ret;
|
||||
|
||||
otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
|
||||
@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
|
||||
|
||||
otp->dev = dev;
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
|
||||
- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
|
||||
if (IS_ERR(otp->base[HB_GPIO]))
|
||||
return PTR_ERR(otp->base[HB_GPIO]);
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
|
||||
- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
|
||||
if (IS_ERR(otp->base[OTPRX]))
|
||||
return PTR_ERR(otp->base[OTPRX]);
|
||||
|
@ -0,0 +1,525 @@
|
||||
From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Mon, 2 Sep 2024 15:29:47 +0100
|
||||
Subject: [PATCH] nvmem: layouts: add U-Boot env layout
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
U-Boot environment variables are stored in a specific format. Actual
|
||||
data can be placed in various storage sources (MTD, UBI volume, EEPROM,
|
||||
NVRAM, etc.).
|
||||
|
||||
Move all generic (NVMEM device independent) code from NVMEM device
|
||||
driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
|
||||
top of it.
|
||||
|
||||
This allows using NVMEM layout for parsing U-Boot env data stored in any
|
||||
kind of NVMEM device.
|
||||
|
||||
The old NVMEM glue driver stays in place for handling bindings in the
|
||||
MTD context. To avoid code duplication it uses exported layout parsing
|
||||
function. Please note that handling MTD & NVMEM layout bindings may be
|
||||
refactored in the future.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/nvmem/Kconfig | 3 +-
|
||||
drivers/nvmem/layouts/Kconfig | 11 ++
|
||||
drivers/nvmem/layouts/Makefile | 1 +
|
||||
drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
|
||||
drivers/nvmem/layouts/u-boot-env.h | 15 ++
|
||||
drivers/nvmem/u-boot-env.c | 165 +---------------------
|
||||
7 files changed, 242 insertions(+), 165 deletions(-)
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.c
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.h
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -21033,6 +21033,7 @@ U-BOOT ENVIRONMENT VARIABLES
|
||||
M: Rafał Miłecki <rafal@milecki.pl>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
|
||||
+F: drivers/nvmem/layouts/u-boot-env.c
|
||||
F: drivers/nvmem/u-boot-env.c
|
||||
|
||||
UACCE ACCELERATOR FRAMEWORK
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
|
||||
config NVMEM_U_BOOT_ENV
|
||||
tristate "U-Boot environment variables support"
|
||||
depends on OF && MTD
|
||||
- select CRC32
|
||||
- select GENERIC_NET_UTILS
|
||||
+ select NVMEM_LAYOUT_U_BOOT_ENV
|
||||
help
|
||||
U-Boot stores its setup as environment variables. This driver adds
|
||||
support for verifying & exporting such data. It also exposes variables
|
||||
--- a/drivers/nvmem/layouts/Kconfig
|
||||
+++ b/drivers/nvmem/layouts/Kconfig
|
||||
@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config NVMEM_LAYOUT_U_BOOT_ENV
|
||||
+ tristate "U-Boot environment variables layout"
|
||||
+ select CRC32
|
||||
+ select GENERIC_NET_UTILS
|
||||
+ help
|
||||
+ U-Boot stores its setup as environment variables. This driver adds
|
||||
+ support for verifying & exporting such data. It also exposes variables
|
||||
+ as NVMEM cells so they can be referenced by other drivers.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/drivers/nvmem/layouts/Makefile
|
||||
+++ b/drivers/nvmem/layouts/Makefile
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
|
||||
+obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -0,0 +1,211 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/crc32.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/if_ether.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/nvmem-provider.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include "u-boot-env.h"
|
||||
+
|
||||
+struct u_boot_env_image_single {
|
||||
+ __le32 crc32;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_redundant {
|
||||
+ __le32 crc32;
|
||||
+ u8 mark;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_broadcom {
|
||||
+ __le32 magic;
|
||||
+ __le32 len;
|
||||
+ __le32 crc32;
|
||||
+ DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
+} __packed;
|
||||
+
|
||||
+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
+ unsigned int offset, void *buf, size_t bytes)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (bytes != 3 * ETH_ALEN - 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (index)
|
||||
+ eth_addr_add(mac, index);
|
||||
+
|
||||
+ ether_addr_copy(buf, mac);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
|
||||
+ size_t data_offset, size_t data_len)
|
||||
+{
|
||||
+ char *data = buf + data_offset;
|
||||
+ char *var, *value, *eq;
|
||||
+
|
||||
+ for (var = data;
|
||||
+ var < data + data_len && *var;
|
||||
+ var = value + strlen(value) + 1) {
|
||||
+ struct nvmem_cell_info info = {};
|
||||
+
|
||||
+ eq = strchr(var, '=');
|
||||
+ if (!eq)
|
||||
+ break;
|
||||
+ *eq = '\0';
|
||||
+ value = eq + 1;
|
||||
+
|
||||
+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
+ if (!info.name)
|
||||
+ return -ENOMEM;
|
||||
+ info.offset = data_offset + value - data;
|
||||
+ info.bytes = strlen(value);
|
||||
+ info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
+ if (!strcmp(var, "ethaddr")) {
|
||||
+ info.raw_len = strlen(value);
|
||||
+ info.bytes = ETH_ALEN;
|
||||
+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
+ }
|
||||
+
|
||||
+ nvmem_add_one_cell(nvmem, &info);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format)
|
||||
+{
|
||||
+ size_t crc32_data_offset;
|
||||
+ size_t crc32_data_len;
|
||||
+ size_t crc32_offset;
|
||||
+ __le32 *crc32_addr;
|
||||
+ size_t data_offset;
|
||||
+ size_t data_len;
|
||||
+ size_t dev_size;
|
||||
+ uint32_t crc32;
|
||||
+ uint32_t calc;
|
||||
+ uint8_t *buf;
|
||||
+ int bytes;
|
||||
+ int err;
|
||||
+
|
||||
+ dev_size = nvmem_dev_size(nvmem);
|
||||
+
|
||||
+ buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
+ if (!buf) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
+ if (bytes < 0) {
|
||||
+ err = bytes;
|
||||
+ goto err_kfree;
|
||||
+ } else if (bytes != dev_size) {
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ switch (format) {
|
||||
+ case U_BOOT_FORMAT_SINGLE:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_REDUNDANT:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_BROADCOM:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev_size < data_offset) {
|
||||
+ dev_err(dev, "Device too small for u-boot-env\n");
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
+ crc32 = le32_to_cpu(*crc32_addr);
|
||||
+ crc32_data_len = dev_size - crc32_data_offset;
|
||||
+ data_len = dev_size - data_offset;
|
||||
+
|
||||
+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
+ if (calc != crc32) {
|
||||
+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
+ err = -EINVAL;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ buf[dev_size - 1] = '\0';
|
||||
+ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
|
||||
+
|
||||
+err_kfree:
|
||||
+ kfree(buf);
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(u_boot_env_parse);
|
||||
+
|
||||
+static int u_boot_env_add_cells(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ struct device *dev = &layout->dev;
|
||||
+ enum u_boot_env_format format;
|
||||
+
|
||||
+ format = (uintptr_t)device_get_match_data(dev);
|
||||
+
|
||||
+ return u_boot_env_parse(dev, layout->nvmem, format);
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_probe(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ layout->add_cells = u_boot_env_add_cells;
|
||||
+
|
||||
+ return nvmem_layout_register(layout);
|
||||
+}
|
||||
+
|
||||
+static void u_boot_env_remove(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ nvmem_layout_unregister(layout);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id u_boot_env_of_match_table[] = {
|
||||
+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
|
||||
+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static struct nvmem_layout_driver u_boot_env_layout = {
|
||||
+ .driver = {
|
||||
+ .name = "u-boot-env-layout",
|
||||
+ .of_match_table = u_boot_env_of_match_table,
|
||||
+ },
|
||||
+ .probe = u_boot_env_probe,
|
||||
+ .remove = u_boot_env_remove,
|
||||
+};
|
||||
+module_nvmem_layout_driver(u_boot_env_layout);
|
||||
+
|
||||
+MODULE_AUTHOR("Rafał Miłecki");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
|
||||
+MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+
|
||||
+#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+
|
||||
+enum u_boot_env_format {
|
||||
+ U_BOOT_FORMAT_SINGLE,
|
||||
+ U_BOOT_FORMAT_REDUNDANT,
|
||||
+ U_BOOT_FORMAT_BROADCOM,
|
||||
+};
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format);
|
||||
+
|
||||
+#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -3,23 +3,15 @@
|
||||
* Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
|
||||
*/
|
||||
|
||||
-#include <linux/crc32.h>
|
||||
-#include <linux/etherdevice.h>
|
||||
-#include <linux/if_ether.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
-#include <linux/nvmem-consumer.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
-enum u_boot_env_format {
|
||||
- U_BOOT_FORMAT_SINGLE,
|
||||
- U_BOOT_FORMAT_REDUNDANT,
|
||||
- U_BOOT_FORMAT_BROADCOM,
|
||||
-};
|
||||
+#include "layouts/u-boot-env.h"
|
||||
|
||||
struct u_boot_env {
|
||||
struct device *dev;
|
||||
@@ -29,24 +21,6 @@ struct u_boot_env {
|
||||
struct mtd_info *mtd;
|
||||
};
|
||||
|
||||
-struct u_boot_env_image_single {
|
||||
- __le32 crc32;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_redundant {
|
||||
- __le32 crc32;
|
||||
- u8 mark;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_broadcom {
|
||||
- __le32 magic;
|
||||
- __le32 len;
|
||||
- __le32 crc32;
|
||||
- DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
-} __packed;
|
||||
-
|
||||
static int u_boot_env_read(void *context, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
- unsigned int offset, void *buf, size_t bytes)
|
||||
-{
|
||||
- u8 mac[ETH_ALEN];
|
||||
-
|
||||
- if (bytes != 3 * ETH_ALEN - 1)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (!mac_pton(buf, mac))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (index)
|
||||
- eth_addr_add(mac, index);
|
||||
-
|
||||
- ether_addr_copy(buf, mac);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
|
||||
- size_t data_offset, size_t data_len)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- char *data = buf + data_offset;
|
||||
- char *var, *value, *eq;
|
||||
-
|
||||
- for (var = data;
|
||||
- var < data + data_len && *var;
|
||||
- var = value + strlen(value) + 1) {
|
||||
- struct nvmem_cell_info info = {};
|
||||
-
|
||||
- eq = strchr(var, '=');
|
||||
- if (!eq)
|
||||
- break;
|
||||
- *eq = '\0';
|
||||
- value = eq + 1;
|
||||
-
|
||||
- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
- if (!info.name)
|
||||
- return -ENOMEM;
|
||||
- info.offset = data_offset + value - data;
|
||||
- info.bytes = strlen(value);
|
||||
- info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
- if (!strcmp(var, "ethaddr")) {
|
||||
- info.raw_len = strlen(value);
|
||||
- info.bytes = ETH_ALEN;
|
||||
- info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
- }
|
||||
-
|
||||
- nvmem_add_one_cell(nvmem, &info);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_parse(struct u_boot_env *priv)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- size_t crc32_data_offset;
|
||||
- size_t crc32_data_len;
|
||||
- size_t crc32_offset;
|
||||
- __le32 *crc32_addr;
|
||||
- size_t data_offset;
|
||||
- size_t data_len;
|
||||
- size_t dev_size;
|
||||
- uint32_t crc32;
|
||||
- uint32_t calc;
|
||||
- uint8_t *buf;
|
||||
- int bytes;
|
||||
- int err;
|
||||
-
|
||||
- dev_size = nvmem_dev_size(nvmem);
|
||||
-
|
||||
- buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
- if (!buf) {
|
||||
- err = -ENOMEM;
|
||||
- goto err_out;
|
||||
- }
|
||||
-
|
||||
- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
- if (bytes < 0) {
|
||||
- err = bytes;
|
||||
- goto err_kfree;
|
||||
- } else if (bytes != dev_size) {
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- switch (priv->format) {
|
||||
- case U_BOOT_FORMAT_SINGLE:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_REDUNDANT:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_BROADCOM:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (dev_size < data_offset) {
|
||||
- dev_err(dev, "Device too small for u-boot-env\n");
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
- crc32 = le32_to_cpu(*crc32_addr);
|
||||
- crc32_data_len = dev_size - crc32_data_offset;
|
||||
- data_len = dev_size - data_offset;
|
||||
-
|
||||
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
- if (calc != crc32) {
|
||||
- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
- err = -EINVAL;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- buf[dev_size - 1] = '\0';
|
||||
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
|
||||
-
|
||||
-err_kfree:
|
||||
- kfree(buf);
|
||||
-err_out:
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static int u_boot_env_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct nvmem_config config = {
|
||||
@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
|
||||
if (IS_ERR(priv->nvmem))
|
||||
return PTR_ERR(priv->nvmem);
|
||||
|
||||
- return u_boot_env_parse(priv);
|
||||
+ return u_boot_env_parse(dev, priv->nvmem, priv->format);
|
||||
}
|
||||
|
||||
static const struct of_device_id u_boot_env_of_match_table[] = {
|
@ -0,0 +1,73 @@
|
||||
From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
|
||||
From: Peng Fan <peng.fan@nxp.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:45 +0100
|
||||
Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
|
||||
|
||||
i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
|
||||
some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
|
||||
|
||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
|
||||
1 file changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/imx-ocotp-ele.c
|
||||
+++ b/drivers/nvmem/imx-ocotp-ele.c
|
||||
@@ -14,8 +14,9 @@
|
||||
#include <linux/slab.h>
|
||||
|
||||
enum fuse_type {
|
||||
- FUSE_FSB = 1,
|
||||
- FUSE_ELE = 2,
|
||||
+ FUSE_FSB = BIT(0),
|
||||
+ FUSE_ELE = BIT(1),
|
||||
+ FUSE_ECC = BIT(2),
|
||||
FUSE_INVALID = -1
|
||||
};
|
||||
|
||||
@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
|
||||
continue;
|
||||
}
|
||||
|
||||
- *buf++ = readl_relaxed(reg + (i << 2));
|
||||
+ if (type & FUSE_ECC)
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
|
||||
+ else
|
||||
+ *buf++ = readl_relaxed(reg + (i << 2));
|
||||
}
|
||||
|
||||
memcpy(val, (u8 *)p, bytes);
|
||||
@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct ocotp_devtype_data imx95_ocotp_data = {
|
||||
+ .reg_off = 0x8000,
|
||||
+ .reg_read = imx_ocotp_reg_read,
|
||||
+ .size = 2048,
|
||||
+ .num_entry = 12,
|
||||
+ .entry = {
|
||||
+ { 0, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 7, 1, FUSE_FSB | FUSE_ECC },
|
||||
+ { 9, 3, FUSE_FSB | FUSE_ECC },
|
||||
+ { 12, 24, FUSE_FSB },
|
||||
+ { 36, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 38, 14, FUSE_FSB },
|
||||
+ { 63, 1, FUSE_ELE },
|
||||
+ { 128, 16, FUSE_ELE },
|
||||
+ { 188, 1, FUSE_ELE },
|
||||
+ { 317, 2, FUSE_FSB | FUSE_ECC },
|
||||
+ { 320, 7, FUSE_FSB },
|
||||
+ { 328, 184, FUSE_FSB }
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
|
||||
+ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
|
@ -0,0 +1,44 @@
|
||||
From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Date: Mon, 2 Sep 2024 15:29:50 +0100
|
||||
Subject: [PATCH] nvmem: sunplus-ocotp: Use
|
||||
devm_platform_ioremap_resource_byname() helper function
|
||||
|
||||
platform_get_resource_byname() and devm_ioremap_resource() can be
|
||||
replaced by devm_platform_ioremap_resource_byname(), which can
|
||||
simplify the code logic a bit, No functional change here.
|
||||
|
||||
Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/sunplus-ocotp.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/sunplus-ocotp.c
|
||||
+++ b/drivers/nvmem/sunplus-ocotp.c
|
||||
@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
|
||||
struct device *dev = &pdev->dev;
|
||||
struct nvmem_device *nvmem;
|
||||
struct sp_ocotp_priv *otp;
|
||||
- struct resource *res;
|
||||
int ret;
|
||||
|
||||
otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
|
||||
@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
|
||||
|
||||
otp->dev = dev;
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
|
||||
- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
|
||||
if (IS_ERR(otp->base[HB_GPIO]))
|
||||
return PTR_ERR(otp->base[HB_GPIO]);
|
||||
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
|
||||
- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
|
||||
+ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
|
||||
if (IS_ERR(otp->base[OTPRX]))
|
||||
return PTR_ERR(otp->base[OTPRX]);
|
||||
|
@ -0,0 +1,525 @@
|
||||
From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Mon, 2 Sep 2024 15:29:47 +0100
|
||||
Subject: [PATCH] nvmem: layouts: add U-Boot env layout
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
U-Boot environment variables are stored in a specific format. Actual
|
||||
data can be placed in various storage sources (MTD, UBI volume, EEPROM,
|
||||
NVRAM, etc.).
|
||||
|
||||
Move all generic (NVMEM device independent) code from NVMEM device
|
||||
driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
|
||||
top of it.
|
||||
|
||||
This allows using NVMEM layout for parsing U-Boot env data stored in any
|
||||
kind of NVMEM device.
|
||||
|
||||
The old NVMEM glue driver stays in place for handling bindings in the
|
||||
MTD context. To avoid code duplication it uses exported layout parsing
|
||||
function. Please note that handling MTD & NVMEM layout bindings may be
|
||||
refactored in the future.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/nvmem/Kconfig | 3 +-
|
||||
drivers/nvmem/layouts/Kconfig | 11 ++
|
||||
drivers/nvmem/layouts/Makefile | 1 +
|
||||
drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
|
||||
drivers/nvmem/layouts/u-boot-env.h | 15 ++
|
||||
drivers/nvmem/u-boot-env.c | 165 +---------------------
|
||||
7 files changed, 242 insertions(+), 165 deletions(-)
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.c
|
||||
create mode 100644 drivers/nvmem/layouts/u-boot-env.h
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -21988,6 +21988,7 @@ U-BOOT ENVIRONMENT VARIABLES
|
||||
M: Rafał Miłecki <rafal@milecki.pl>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
|
||||
+F: drivers/nvmem/layouts/u-boot-env.c
|
||||
F: drivers/nvmem/u-boot-env.c
|
||||
|
||||
UACCE ACCELERATOR FRAMEWORK
|
||||
--- a/drivers/nvmem/Kconfig
|
||||
+++ b/drivers/nvmem/Kconfig
|
||||
@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
|
||||
config NVMEM_U_BOOT_ENV
|
||||
tristate "U-Boot environment variables support"
|
||||
depends on OF && MTD
|
||||
- select CRC32
|
||||
- select GENERIC_NET_UTILS
|
||||
+ select NVMEM_LAYOUT_U_BOOT_ENV
|
||||
help
|
||||
U-Boot stores its setup as environment variables. This driver adds
|
||||
support for verifying & exporting such data. It also exposes variables
|
||||
--- a/drivers/nvmem/layouts/Kconfig
|
||||
+++ b/drivers/nvmem/layouts/Kconfig
|
||||
@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config NVMEM_LAYOUT_U_BOOT_ENV
|
||||
+ tristate "U-Boot environment variables layout"
|
||||
+ select CRC32
|
||||
+ select GENERIC_NET_UTILS
|
||||
+ help
|
||||
+ U-Boot stores its setup as environment variables. This driver adds
|
||||
+ support for verifying & exporting such data. It also exposes variables
|
||||
+ as NVMEM cells so they can be referenced by other drivers.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
endmenu
|
||||
|
||||
endif
|
||||
--- a/drivers/nvmem/layouts/Makefile
|
||||
+++ b/drivers/nvmem/layouts/Makefile
|
||||
@@ -5,3 +5,4 @@
|
||||
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
|
||||
obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
|
||||
+obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -0,0 +1,211 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/crc32.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/if_ether.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/nvmem-provider.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include "u-boot-env.h"
|
||||
+
|
||||
+struct u_boot_env_image_single {
|
||||
+ __le32 crc32;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_redundant {
|
||||
+ __le32 crc32;
|
||||
+ u8 mark;
|
||||
+ uint8_t data[];
|
||||
+} __packed;
|
||||
+
|
||||
+struct u_boot_env_image_broadcom {
|
||||
+ __le32 magic;
|
||||
+ __le32 len;
|
||||
+ __le32 crc32;
|
||||
+ DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
+} __packed;
|
||||
+
|
||||
+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
+ unsigned int offset, void *buf, size_t bytes)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (bytes != 3 * ETH_ALEN - 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (index)
|
||||
+ eth_addr_add(mac, index);
|
||||
+
|
||||
+ ether_addr_copy(buf, mac);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
|
||||
+ size_t data_offset, size_t data_len)
|
||||
+{
|
||||
+ char *data = buf + data_offset;
|
||||
+ char *var, *value, *eq;
|
||||
+
|
||||
+ for (var = data;
|
||||
+ var < data + data_len && *var;
|
||||
+ var = value + strlen(value) + 1) {
|
||||
+ struct nvmem_cell_info info = {};
|
||||
+
|
||||
+ eq = strchr(var, '=');
|
||||
+ if (!eq)
|
||||
+ break;
|
||||
+ *eq = '\0';
|
||||
+ value = eq + 1;
|
||||
+
|
||||
+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
+ if (!info.name)
|
||||
+ return -ENOMEM;
|
||||
+ info.offset = data_offset + value - data;
|
||||
+ info.bytes = strlen(value);
|
||||
+ info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
+ if (!strcmp(var, "ethaddr")) {
|
||||
+ info.raw_len = strlen(value);
|
||||
+ info.bytes = ETH_ALEN;
|
||||
+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
+ }
|
||||
+
|
||||
+ nvmem_add_one_cell(nvmem, &info);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format)
|
||||
+{
|
||||
+ size_t crc32_data_offset;
|
||||
+ size_t crc32_data_len;
|
||||
+ size_t crc32_offset;
|
||||
+ __le32 *crc32_addr;
|
||||
+ size_t data_offset;
|
||||
+ size_t data_len;
|
||||
+ size_t dev_size;
|
||||
+ uint32_t crc32;
|
||||
+ uint32_t calc;
|
||||
+ uint8_t *buf;
|
||||
+ int bytes;
|
||||
+ int err;
|
||||
+
|
||||
+ dev_size = nvmem_dev_size(nvmem);
|
||||
+
|
||||
+ buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
+ if (!buf) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
+ if (bytes < 0) {
|
||||
+ err = bytes;
|
||||
+ goto err_kfree;
|
||||
+ } else if (bytes != dev_size) {
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ switch (format) {
|
||||
+ case U_BOOT_FORMAT_SINGLE:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_REDUNDANT:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
+ break;
|
||||
+ case U_BOOT_FORMAT_BROADCOM:
|
||||
+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev_size < data_offset) {
|
||||
+ dev_err(dev, "Device too small for u-boot-env\n");
|
||||
+ err = -EIO;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
+ crc32 = le32_to_cpu(*crc32_addr);
|
||||
+ crc32_data_len = dev_size - crc32_data_offset;
|
||||
+ data_len = dev_size - data_offset;
|
||||
+
|
||||
+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
+ if (calc != crc32) {
|
||||
+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
+ err = -EINVAL;
|
||||
+ goto err_kfree;
|
||||
+ }
|
||||
+
|
||||
+ buf[dev_size - 1] = '\0';
|
||||
+ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
|
||||
+
|
||||
+err_kfree:
|
||||
+ kfree(buf);
|
||||
+err_out:
|
||||
+ return err;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(u_boot_env_parse);
|
||||
+
|
||||
+static int u_boot_env_add_cells(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ struct device *dev = &layout->dev;
|
||||
+ enum u_boot_env_format format;
|
||||
+
|
||||
+ format = (uintptr_t)device_get_match_data(dev);
|
||||
+
|
||||
+ return u_boot_env_parse(dev, layout->nvmem, format);
|
||||
+}
|
||||
+
|
||||
+static int u_boot_env_probe(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ layout->add_cells = u_boot_env_add_cells;
|
||||
+
|
||||
+ return nvmem_layout_register(layout);
|
||||
+}
|
||||
+
|
||||
+static void u_boot_env_remove(struct nvmem_layout *layout)
|
||||
+{
|
||||
+ nvmem_layout_unregister(layout);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id u_boot_env_of_match_table[] = {
|
||||
+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
|
||||
+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
|
||||
+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static struct nvmem_layout_driver u_boot_env_layout = {
|
||||
+ .driver = {
|
||||
+ .name = "u-boot-env-layout",
|
||||
+ .of_match_table = u_boot_env_of_match_table,
|
||||
+ },
|
||||
+ .probe = u_boot_env_probe,
|
||||
+ .remove = u_boot_env_remove,
|
||||
+};
|
||||
+module_nvmem_layout_driver(u_boot_env_layout);
|
||||
+
|
||||
+MODULE_AUTHOR("Rafał Miłecki");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
|
||||
+MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
|
||||
--- /dev/null
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+
|
||||
+#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
|
||||
+
|
||||
+enum u_boot_env_format {
|
||||
+ U_BOOT_FORMAT_SINGLE,
|
||||
+ U_BOOT_FORMAT_REDUNDANT,
|
||||
+ U_BOOT_FORMAT_BROADCOM,
|
||||
+};
|
||||
+
|
||||
+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
|
||||
+ enum u_boot_env_format format);
|
||||
+
|
||||
+#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -3,23 +3,15 @@
|
||||
* Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
|
||||
*/
|
||||
|
||||
-#include <linux/crc32.h>
|
||||
-#include <linux/etherdevice.h>
|
||||
-#include <linux/if_ether.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
-#include <linux/nvmem-consumer.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
-enum u_boot_env_format {
|
||||
- U_BOOT_FORMAT_SINGLE,
|
||||
- U_BOOT_FORMAT_REDUNDANT,
|
||||
- U_BOOT_FORMAT_BROADCOM,
|
||||
-};
|
||||
+#include "layouts/u-boot-env.h"
|
||||
|
||||
struct u_boot_env {
|
||||
struct device *dev;
|
||||
@@ -29,24 +21,6 @@ struct u_boot_env {
|
||||
struct mtd_info *mtd;
|
||||
};
|
||||
|
||||
-struct u_boot_env_image_single {
|
||||
- __le32 crc32;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_redundant {
|
||||
- __le32 crc32;
|
||||
- u8 mark;
|
||||
- uint8_t data[];
|
||||
-} __packed;
|
||||
-
|
||||
-struct u_boot_env_image_broadcom {
|
||||
- __le32 magic;
|
||||
- __le32 len;
|
||||
- __le32 crc32;
|
||||
- DECLARE_FLEX_ARRAY(uint8_t, data);
|
||||
-} __packed;
|
||||
-
|
||||
static int u_boot_env_read(void *context, unsigned int offset, void *val,
|
||||
size_t bytes)
|
||||
{
|
||||
@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
|
||||
- unsigned int offset, void *buf, size_t bytes)
|
||||
-{
|
||||
- u8 mac[ETH_ALEN];
|
||||
-
|
||||
- if (bytes != 3 * ETH_ALEN - 1)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (!mac_pton(buf, mac))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (index)
|
||||
- eth_addr_add(mac, index);
|
||||
-
|
||||
- ether_addr_copy(buf, mac);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
|
||||
- size_t data_offset, size_t data_len)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- char *data = buf + data_offset;
|
||||
- char *var, *value, *eq;
|
||||
-
|
||||
- for (var = data;
|
||||
- var < data + data_len && *var;
|
||||
- var = value + strlen(value) + 1) {
|
||||
- struct nvmem_cell_info info = {};
|
||||
-
|
||||
- eq = strchr(var, '=');
|
||||
- if (!eq)
|
||||
- break;
|
||||
- *eq = '\0';
|
||||
- value = eq + 1;
|
||||
-
|
||||
- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||
- if (!info.name)
|
||||
- return -ENOMEM;
|
||||
- info.offset = data_offset + value - data;
|
||||
- info.bytes = strlen(value);
|
||||
- info.np = of_get_child_by_name(dev->of_node, info.name);
|
||||
- if (!strcmp(var, "ethaddr")) {
|
||||
- info.raw_len = strlen(value);
|
||||
- info.bytes = ETH_ALEN;
|
||||
- info.read_post_process = u_boot_env_read_post_process_ethaddr;
|
||||
- }
|
||||
-
|
||||
- nvmem_add_one_cell(nvmem, &info);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int u_boot_env_parse(struct u_boot_env *priv)
|
||||
-{
|
||||
- struct nvmem_device *nvmem = priv->nvmem;
|
||||
- struct device *dev = priv->dev;
|
||||
- size_t crc32_data_offset;
|
||||
- size_t crc32_data_len;
|
||||
- size_t crc32_offset;
|
||||
- __le32 *crc32_addr;
|
||||
- size_t data_offset;
|
||||
- size_t data_len;
|
||||
- size_t dev_size;
|
||||
- uint32_t crc32;
|
||||
- uint32_t calc;
|
||||
- uint8_t *buf;
|
||||
- int bytes;
|
||||
- int err;
|
||||
-
|
||||
- dev_size = nvmem_dev_size(nvmem);
|
||||
-
|
||||
- buf = kzalloc(dev_size, GFP_KERNEL);
|
||||
- if (!buf) {
|
||||
- err = -ENOMEM;
|
||||
- goto err_out;
|
||||
- }
|
||||
-
|
||||
- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
|
||||
- if (bytes < 0) {
|
||||
- err = bytes;
|
||||
- goto err_kfree;
|
||||
- } else if (bytes != dev_size) {
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- switch (priv->format) {
|
||||
- case U_BOOT_FORMAT_SINGLE:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_single, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_REDUNDANT:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_redundant, data);
|
||||
- break;
|
||||
- case U_BOOT_FORMAT_BROADCOM:
|
||||
- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
|
||||
- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (dev_size < data_offset) {
|
||||
- dev_err(dev, "Device too small for u-boot-env\n");
|
||||
- err = -EIO;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- crc32_addr = (__le32 *)(buf + crc32_offset);
|
||||
- crc32 = le32_to_cpu(*crc32_addr);
|
||||
- crc32_data_len = dev_size - crc32_data_offset;
|
||||
- data_len = dev_size - data_offset;
|
||||
-
|
||||
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
|
||||
- if (calc != crc32) {
|
||||
- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
|
||||
- err = -EINVAL;
|
||||
- goto err_kfree;
|
||||
- }
|
||||
-
|
||||
- buf[dev_size - 1] = '\0';
|
||||
- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
|
||||
-
|
||||
-err_kfree:
|
||||
- kfree(buf);
|
||||
-err_out:
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
static int u_boot_env_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct nvmem_config config = {
|
||||
@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
|
||||
if (IS_ERR(priv->nvmem))
|
||||
return PTR_ERR(priv->nvmem);
|
||||
|
||||
- return u_boot_env_parse(priv);
|
||||
+ return u_boot_env_parse(dev, priv->nvmem, priv->format);
|
||||
}
|
||||
|
||||
static const struct of_device_id u_boot_env_of_match_table[] = {
|
@ -4453,6 +4453,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
|
||||
# CONFIG_NVMEM_IMX_OCOTP is not set
|
||||
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
|
||||
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
|
||||
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
|
||||
# CONFIG_NVMEM_REBOOT_MODE is not set
|
||||
# CONFIG_NVMEM_RMEM is not set
|
||||
# CONFIG_NVMEM_SYSFS is not set
|
||||
|
@ -4624,6 +4624,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
|
||||
# CONFIG_NVMEM_IMX_OCOTP is not set
|
||||
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
|
||||
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
|
||||
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
|
||||
# CONFIG_NVMEM_REBOOT_MODE is not set
|
||||
# CONFIG_NVMEM_RMEM is not set
|
||||
# CONFIG_NVMEM_SYSFS is not set
|
||||
|
@ -4335,6 +4335,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
|
||||
# CONFIG_NVMEM_IMX_OCOTP is not set
|
||||
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
|
||||
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
|
||||
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
|
||||
# CONFIG_NVMEM_REBOOT_MODE is not set
|
||||
# CONFIG_NVMEM_RMEM is not set
|
||||
# CONFIG_NVMEM_SYSFS is not set
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
|
||||
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||
Date: Thu, 13 Oct 2022 00:51:33 +0900
|
||||
Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
|
||||
Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Tested-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
---
|
||||
drivers/nvmem/u-boot-env.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -188,7 +188,7 @@ static int u_boot_env_parse(struct u_boo
|
||||
--- a/drivers/nvmem/layouts/u-boot-env.c
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
|
||||
crc32_data_len = dev_size - crc32_data_offset;
|
||||
data_len = dev_size - data_offset;
|
||||
|
||||
|
@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -21059,6 +21059,12 @@ F: Documentation/filesystems/ubifs-authe
|
||||
@@ -21060,6 +21060,12 @@ F: Documentation/filesystems/ubifs-authe
|
||||
F: Documentation/filesystems/ubifs.rst
|
||||
F: fs/ubifs/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
|
||||
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||
Date: Thu, 13 Oct 2022 00:51:33 +0900
|
||||
Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
|
||||
Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Tested-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
---
|
||||
drivers/nvmem/u-boot-env.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -188,7 +188,7 @@ static int u_boot_env_parse(struct u_boo
|
||||
--- a/drivers/nvmem/layouts/u-boot-env.c
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
|
||||
crc32_data_len = dev_size - crc32_data_offset;
|
||||
data_len = dev_size - data_offset;
|
||||
|
||||
|
@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -22014,6 +22014,12 @@ F: Documentation/filesystems/ubifs-authe
|
||||
@@ -22015,6 +22015,12 @@ F: Documentation/filesystems/ubifs-authe
|
||||
F: Documentation/filesystems/ubifs.rst
|
||||
F: fs/ubifs/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
|
||||
From: INAGAKI Hiroshi <musashino.open@gmail.com>
|
||||
Date: Thu, 13 Oct 2022 00:51:33 +0900
|
||||
Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
|
||||
Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Tested-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
---
|
||||
drivers/nvmem/u-boot-env.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/u-boot-env.c
|
||||
+++ b/drivers/nvmem/u-boot-env.c
|
||||
@@ -188,7 +188,7 @@ static int u_boot_env_parse(struct u_boo
|
||||
--- a/drivers/nvmem/layouts/u-boot-env.c
|
||||
+++ b/drivers/nvmem/layouts/u-boot-env.c
|
||||
@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
|
||||
crc32_data_len = dev_size - crc32_data_offset;
|
||||
data_len = dev_size - data_offset;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user