Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
5c3b835e30
@ -5,9 +5,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||
PKG_SOURCE_DATE:=2024-09-05
|
||||
PKG_SOURCE_VERSION:=61c606d6e66b132f602135e0f0fda5f532b588e9
|
||||
PKG_MIRROR_HASH:=9fc091803545b0314c888e74ea7cecb5c4f8dbdb9b832bb5595378e67fd06ea3
|
||||
PKG_SOURCE_DATE:=2024-09-12
|
||||
PKG_SOURCE_VERSION:=02aa43d82d587d87523231be5a5e0bf956435725
|
||||
PKG_MIRROR_HASH:=a0e997ed9b0191417e65aaf43fbfd3a51b734ce1ea83f87e2d71b904b5a368ca
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=ct-bugcheck
|
||||
PKG_RELEASE:=2016-07-21
|
||||
PKG_RELEASE:=2016.07.21
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
|
||||
@ -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[] = {
|
||||
@ -4472,6 +4472,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
|
||||
|
||||
@ -4644,6 +4644,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
|
||||
|
||||
@ -4356,6 +4356,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;
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
*/
|
||||
--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
+++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
|
||||
@@ -109,6 +109,98 @@ int mtk_phy_write_page(struct phy_device
|
||||
@@ -109,6 +109,108 @@ int mtk_phy_write_page(struct phy_device
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtk_phy_write_page);
|
||||
|
||||
@ -79,7 +79,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+ */
|
||||
+static int extend_an_new_lp_cnt_limit(struct phy_device *phydev)
|
||||
+{
|
||||
+ int mmd_read_ret;
|
||||
+ int ret;
|
||||
+ u32 reg_val;
|
||||
+ int timeout;
|
||||
+
|
||||
@ -90,13 +90,14 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+ * this PHY's 1G training starts. If 1G training never starts, we do
|
||||
+ * nothing but leave.
|
||||
+ */
|
||||
+ timeout = read_poll_timeout(mmd_read_ret = phy_read_mmd, reg_val,
|
||||
+ (mmd_read_ret < 0) ||
|
||||
+ timeout = read_poll_timeout(ret = phy_read_mmd, reg_val,
|
||||
+ (ret < 0) ||
|
||||
+ reg_val & MTK_PHY_FINAL_SPEED_1000,
|
||||
+ 10000, 1000000, false, phydev,
|
||||
+ 10000, 500000, false, phydev,
|
||||
+ MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
|
||||
+ if (mmd_read_ret < 0)
|
||||
+ return mmd_read_ret;
|
||||
+ phydev_dbg(phydev, "%s: Training Indicator: 0x%x\n", __func__, reg_val);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!timeout) {
|
||||
+ /* Once we found MTK_PHY_FINAL_SPEED_1000 is set, no matter 1G
|
||||
@ -105,7 +106,16 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+ */
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK, 0xf));
|
||||
+ mdelay(1500);
|
||||
+ msleep(1500);
|
||||
+
|
||||
+ /* Read phy status again to make sure the following step won't
|
||||
+ * affect normal devices.
|
||||
+ */
|
||||
+ ret = genphy_read_status(phydev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (phydev->link)
|
||||
+ return 0;
|
||||
+
|
||||
+ timeout = read_poll_timeout(mtk_tr_read, reg_val,
|
||||
+ (reg_val & AN_STATE_MASK) !=
|
||||
@ -113,19 +123,18 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+ AN_STATE_SHIFT),
|
||||
+ 10000, 1000000, false, phydev,
|
||||
+ 0x0, 0xf, 0x2);
|
||||
+ phydev_dbg(phydev, "%s: AN State: 0x%x\n", __func__, reg_val);
|
||||
+ if (!timeout) {
|
||||
+ mdelay(625);
|
||||
+ msleep(625);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0x8));
|
||||
+ mdelay(500);
|
||||
+ msleep(500);
|
||||
+ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
|
||||
+ AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
|
||||
+ 0xf));
|
||||
+ } else {
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@ -156,6 +165,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
|
||||
+ ret = phy_read(phydev, MII_CTRL1000);
|
||||
+ if (ret & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) {
|
||||
+ ret = extend_an_new_lp_cnt_limit(phydev);
|
||||
+ phydev_dbg(phydev, "%s: counter limit ret: %d\n", __func__, ret);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user