All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] mtd: core: call devm_of_platform_populate() for MTD devices
@ 2021-12-22 19:23 ` Rafał Miłecki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

This adds support for bindings present in MTD devices (applies to
partitions too) nodes. The purpose of this change is to allow drivers
handle MTD device (partition) data. Some partitions may contain info
that requires parsing & processing.

An example can be U-Boot partition that contains block with environment
variables somehwere in a middle. That block should be described in DT
and parsed by a specific driver.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/mtd/mtdcore.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 70f492dce158..07b75e6ca111 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,6 +19,7 @@
 #include <linux/ioctl.h>
 #include <linux/init.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/proc_fs.h>
 #include <linux/idr.h>
 #include <linux/backing-dev.h>
@@ -690,6 +691,9 @@ int add_mtd_device(struct mtd_info *mtd)
 		not->add(mtd);
 
 	mutex_unlock(&mtd_table_mutex);
+
+	devm_of_platform_populate(&mtd->dev);
+
 	/* We _know_ we aren't being removed, because
 	   our caller is still holding us here. So none
 	   of this try_ nonsense, and no bitching about it
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 1/3] mtd: core: call devm_of_platform_populate() for MTD devices
@ 2021-12-22 19:23 ` Rafał Miłecki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

This adds support for bindings present in MTD devices (applies to
partitions too) nodes. The purpose of this change is to allow drivers
handle MTD device (partition) data. Some partitions may contain info
that requires parsing & processing.

An example can be U-Boot partition that contains block with environment
variables somehwere in a middle. That block should be described in DT
and parsed by a specific driver.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/mtd/mtdcore.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 70f492dce158..07b75e6ca111 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,6 +19,7 @@
 #include <linux/ioctl.h>
 #include <linux/init.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/proc_fs.h>
 #include <linux/idr.h>
 #include <linux/backing-dev.h>
@@ -690,6 +691,9 @@ int add_mtd_device(struct mtd_info *mtd)
 		not->add(mtd);
 
 	mutex_unlock(&mtd_table_mutex);
+
+	devm_of_platform_populate(&mtd->dev);
+
 	/* We _know_ we aren't being removed, because
 	   our caller is still holding us here. So none
 	   of this try_ nonsense, and no bitching about it
-- 
2.31.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] dt-bindings: nvmem: add U-Boot environment variables binding
  2021-12-22 19:23 ` Rafał Miłecki
@ 2021-12-22 19:23   ` Rafał Miłecki
  -1 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

This binding allows describing a (part of) MTD device (partition) that
contains a block with environment variables. Operating system usually
needs to parse that block to read variables values that may affect
booting process & device configuration.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 .../devicetree/bindings/nvmem/u-boot,env.yaml | 56 +++++++++++++++++++
 MAINTAINERS                                   |  5 ++
 2 files changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/u-boot,env.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
new file mode 100644
index 000000000000..0f808868fff3
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/u-boot,env.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: U-Boot environment variables
+
+description: |
+  U-Boot uses environment variables to store device parameters and
+  configuration. They may be used for booting process, setup or keeping end user
+  interesting info.
+
+  Data is stored on flash partition in a U-Boot specific format (CRC32 and NUL
+  separated key-value pairs).
+
+  This binding allows specifying data location and format (default one or vendor
+  specific).
+
+maintainers:
+  - Rafał Miłecki <rafal@milecki.pl>
+
+allOf:
+  - $ref: nvmem.yaml#
+
+properties:
+  compatible:
+    enum:
+      - u,boot,env
+      - brcm,env
+
+  reg:
+    maxItems: 1
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    partitions {
+        compatible = "fixed-partitions";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        partition@0 {
+            label = "uboot";
+            reg = <0x0 0x100000>;
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            nvmem@10000 {
+                compatible = "u,boot,env";
+                reg = <0x10000 0x10000>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 67558097bb66..271c29c84c7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19624,6 +19624,11 @@ W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
 F:	drivers/media/pci/tw686x/
 
+U-BOOT ENVIRONMENT VARIABLES
+M:	Rafał Miłecki <rafal@milecki.pl>
+S:	Maintained
+F:	Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
+
 UACCE ACCELERATOR FRAMEWORK
 M:	Zhangfei Gao <zhangfei.gao@linaro.org>
 M:	Zhou Wang <wangzhou1@hisilicon.com>
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] dt-bindings: nvmem: add U-Boot environment variables binding
@ 2021-12-22 19:23   ` Rafał Miłecki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

This binding allows describing a (part of) MTD device (partition) that
contains a block with environment variables. Operating system usually
needs to parse that block to read variables values that may affect
booting process & device configuration.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 .../devicetree/bindings/nvmem/u-boot,env.yaml | 56 +++++++++++++++++++
 MAINTAINERS                                   |  5 ++
 2 files changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/u-boot,env.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
new file mode 100644
index 000000000000..0f808868fff3
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/u-boot,env.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: U-Boot environment variables
+
+description: |
+  U-Boot uses environment variables to store device parameters and
+  configuration. They may be used for booting process, setup or keeping end user
+  interesting info.
+
+  Data is stored on flash partition in a U-Boot specific format (CRC32 and NUL
+  separated key-value pairs).
+
+  This binding allows specifying data location and format (default one or vendor
+  specific).
+
+maintainers:
+  - Rafał Miłecki <rafal@milecki.pl>
+
+allOf:
+  - $ref: nvmem.yaml#
+
+properties:
+  compatible:
+    enum:
+      - u,boot,env
+      - brcm,env
+
+  reg:
+    maxItems: 1
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    partitions {
+        compatible = "fixed-partitions";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        partition@0 {
+            label = "uboot";
+            reg = <0x0 0x100000>;
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            nvmem@10000 {
+                compatible = "u,boot,env";
+                reg = <0x10000 0x10000>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 67558097bb66..271c29c84c7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19624,6 +19624,11 @@ W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
 F:	drivers/media/pci/tw686x/
 
+U-BOOT ENVIRONMENT VARIABLES
+M:	Rafał Miłecki <rafal@milecki.pl>
+S:	Maintained
+F:	Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
+
 UACCE ACCELERATOR FRAMEWORK
 M:	Zhangfei Gao <zhangfei.gao@linaro.org>
 M:	Zhou Wang <wangzhou1@hisilicon.com>
-- 
2.31.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] nvmem: add driver handling U-Boot environment variables
  2021-12-22 19:23 ` Rafał Miłecki
@ 2021-12-22 19:23   ` Rafał Miłecki
  -1 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

U-Boot binary contains a block of environment variables (NVMEM) that
should be parsed and exposed as NVMEM cells.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 MAINTAINERS                |   1 +
 drivers/nvmem/Kconfig      |  10 ++
 drivers/nvmem/Makefile     |   2 +
 drivers/nvmem/u-boot-env.c | 236 +++++++++++++++++++++++++++++++++++++
 4 files changed, 249 insertions(+)
 create mode 100644 drivers/nvmem/u-boot-env.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 271c29c84c7d..cc9bdeb33b64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19628,6 +19628,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/u-boot-env.c
 
 UACCE ACCELERATOR FRAMEWORK
 M:	Zhangfei Gao <zhangfei.gao@linaro.org>
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index da414617a54d..af9115852412 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -300,4 +300,14 @@ config NVMEM_BRCM_NVRAM
 	  This driver provides support for Broadcom's NVRAM that can be accessed
 	  using I/O mapping.
 
+config NVMEM_U_BOOT_ENV
+	tristate "U-Boot environment variables support"
+	depends on ARCH_BCM4908 || COMPILE_TEST
+	depends on OF
+	help
+	  This driver adds support for parsing U-Boot environment variables
+	  stored on flash partition.
+
+	  If compiled as module it will be called nvmem_u-boot-env.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index dcbbde35b6a8..772904cdebdb 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o
 nvmem-rmem-y			:= rmem.o
 obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o
 nvmem_brcm_nvram-y		:= brcm_nvram.o
+obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o
+nvmem_u-boot-env-y		:= u-boot-env.o
diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c
new file mode 100644
index 000000000000..a932b3d3c63b
--- /dev/null
+++ b/drivers/nvmem/u-boot-env.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+#include <linux/crc32.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_DEFAULT,
+	U_BOOT_FORMAT_BRCM,
+};
+
+struct u_boot_env {
+	struct device *dev;
+	enum u_boot_env_format format;
+	struct mtd_info *mtd;
+	size_t offset;
+	size_t size;
+	struct nvmem_cell_info *cells;
+	int ncells;
+};
+
+struct u_boot_env_image {
+	__le32 crc32;
+	uint8_t data[0];
+} __packed;
+
+struct u_boot_brcm_header {
+	__le32 unk;
+	__le32 len;
+} __packed;
+
+static int u_boot_env_read(void *context, unsigned int offset, void *val,
+			   size_t bytes)
+{
+	struct u_boot_env *priv = context;
+	struct device *dev = priv->dev;
+	size_t bytes_read;
+	int err;
+
+	err = mtd_read(priv->mtd, priv->offset + offset, bytes, &bytes_read, val);
+	if (err && !mtd_is_bitflip(err)) {
+		dev_err(dev, "Failed to read from mtd: %d\n", err);
+		return err;
+	}
+
+	if (bytes_read != bytes) {
+		dev_err(dev, "Failed to read %zd bytes\n", bytes);
+		return err;
+	}
+
+	return 0;
+}
+
+static int u_boot_env_add_cells(struct u_boot_env *priv, size_t data_offset,
+				uint8_t *data, size_t len)
+{
+	struct device *dev = priv->dev;
+	char *var, *value, *eq;
+	int idx;
+
+	priv->ncells = 0;
+	for (var = data; var < (char *)data + len && *var; var += strlen(var) + 1)
+		priv->ncells++;
+
+	priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
+	if (!priv->cells)
+		return -ENOMEM;
+
+	for (var = data, idx = 0;
+	     var < (char *)data + len && *var;
+	     var = value + strlen(value) + 1, idx++) {
+		eq = strchr(var, '=');
+		if (!eq)
+			break;
+		*eq = '\0';
+		value = eq + 1;
+
+		priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
+		if (!priv->cells[idx].name)
+			return -ENOMEM;
+		priv->cells[idx].offset = data_offset + value - (char *)data;
+		priv->cells[idx].bytes = strlen(value);
+	}
+
+	if (WARN_ON(idx != priv->ncells))
+		priv->ncells = idx;
+
+	return 0;
+}
+
+static int u_boot_env_parse(struct u_boot_env *priv)
+{
+	struct device *dev = priv->dev;
+	struct u_boot_env_image *image;
+	size_t image_offset;
+	size_t image_len;
+	uint32_t crc32;
+	size_t bytes;
+	uint8_t *buf;
+	int err;
+
+	image_offset = 0;
+	image_len = priv->size;
+	if (priv->format == U_BOOT_FORMAT_BRCM) {
+		struct u_boot_brcm_header header;
+
+		err = mtd_read(priv->mtd, priv->offset, sizeof(header), &bytes,
+			       (uint8_t *)&header);
+		if (err && !mtd_is_bitflip(err)) {
+			dev_err(dev, "Failed to read from mtd: %d\n", err);
+			return err;
+		}
+
+		image_offset = sizeof(header);
+		image_len = le32_to_cpu(header.len);
+	}
+	dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
+
+	buf = kcalloc(1, image_len, GFP_KERNEL);
+	if (!buf) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	image = (struct u_boot_env_image *)buf;
+
+	err = mtd_read(priv->mtd, priv->offset + image_offset, image_len, &bytes, buf);
+	if (err && !mtd_is_bitflip(err)) {
+		dev_err(dev, "Failed to read from mtd: %d\n", err);
+		goto err_kfree;
+	}
+
+	crc32 = crc32(~0, buf + 4, image_len - 4) ^ ~0L;
+	if (crc32 != le32_to_cpu(image->crc32)) {
+		dev_err(dev, "Invalid calculated CRC32: 0x%08x\n", crc32);
+		err = -EINVAL;
+		goto err_kfree;
+	}
+
+	buf[image_len - 1] = '\0';
+	err = u_boot_env_add_cells(priv, image_offset + sizeof(*image),
+				   buf + sizeof(*image),
+				   image_len - sizeof(*image));
+	if (err)
+		dev_err(dev, "Failed to add cells: %d\n", err);
+
+err_kfree:
+	kfree(buf);
+err_out:
+	return err;
+}
+
+static const struct of_device_id u_boot_env_of_match_table[] = {
+	{ .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_DEFAULT, },
+	{ .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BRCM, },
+	{},
+};
+
+static int u_boot_env_probe(struct platform_device *pdev)
+{
+	struct nvmem_config config = {
+		.name = "u-boot-env",
+		.reg_read = u_boot_env_read,
+	};
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct of_device_id *of_id;
+	struct u_boot_env *priv;
+	const char *label;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	priv->dev = dev;
+
+	of_id = of_match_device(u_boot_env_of_match_table, dev);
+	if (!of_id)
+		return -EINVAL;
+	priv->format = (uintptr_t)of_id->data;
+
+	if (of_property_read_u32(np, "reg", &priv->offset) ||
+	    of_property_read_u32_index(np, "reg", 1, &priv->size)) {
+		dev_err(dev, "Failed to read \"reg\" property\n");
+		return -EINVAL;
+	}
+
+	label = of_get_property(np->parent, "label", NULL);
+	if (!label)
+		label = np->parent->name;
+
+	priv->mtd = get_mtd_device_nm(label);
+	if (IS_ERR(priv->mtd)) {
+		dev_err(dev, "Failed to find \"%s\" MTD device: %ld\n", label, PTR_ERR(priv->mtd));
+		return PTR_ERR(priv->mtd);
+	}
+
+	err = u_boot_env_parse(priv);
+	if (err)
+		return err;
+
+	config.dev = dev;
+	config.cells = priv->cells;
+	config.ncells = priv->ncells;
+	config.priv = priv;
+	config.size = priv->size;
+
+	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
+}
+
+static struct platform_driver u_boot_env_driver = {
+	.probe = u_boot_env_probe,
+	.driver = {
+		.name = "u_boot_env",
+		.of_match_table = u_boot_env_of_match_table,
+	},
+};
+
+static int __init u_boot_env_init(void)
+{
+	return platform_driver_register(&u_boot_env_driver);
+}
+
+subsys_initcall_sync(u_boot_env_init);
+
+MODULE_AUTHOR("Rafał Miłecki");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] nvmem: add driver handling U-Boot environment variables
@ 2021-12-22 19:23   ` Rafał Miłecki
  0 siblings, 0 replies; 11+ messages in thread
From: Rafał Miłecki @ 2021-12-22 19:23 UTC (permalink / raw)
  To: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra
  Cc: devicetree, linux-kernel, linux-mtd, Rafał Miłecki

From: Rafał Miłecki <rafal@milecki.pl>

U-Boot binary contains a block of environment variables (NVMEM) that
should be parsed and exposed as NVMEM cells.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 MAINTAINERS                |   1 +
 drivers/nvmem/Kconfig      |  10 ++
 drivers/nvmem/Makefile     |   2 +
 drivers/nvmem/u-boot-env.c | 236 +++++++++++++++++++++++++++++++++++++
 4 files changed, 249 insertions(+)
 create mode 100644 drivers/nvmem/u-boot-env.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 271c29c84c7d..cc9bdeb33b64 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19628,6 +19628,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/u-boot-env.c
 
 UACCE ACCELERATOR FRAMEWORK
 M:	Zhangfei Gao <zhangfei.gao@linaro.org>
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index da414617a54d..af9115852412 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -300,4 +300,14 @@ config NVMEM_BRCM_NVRAM
 	  This driver provides support for Broadcom's NVRAM that can be accessed
 	  using I/O mapping.
 
+config NVMEM_U_BOOT_ENV
+	tristate "U-Boot environment variables support"
+	depends on ARCH_BCM4908 || COMPILE_TEST
+	depends on OF
+	help
+	  This driver adds support for parsing U-Boot environment variables
+	  stored on flash partition.
+
+	  If compiled as module it will be called nvmem_u-boot-env.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index dcbbde35b6a8..772904cdebdb 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o
 nvmem-rmem-y			:= rmem.o
 obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o
 nvmem_brcm_nvram-y		:= brcm_nvram.o
+obj-$(CONFIG_NVMEM_U_BOOT_ENV)	+= nvmem_u-boot-env.o
+nvmem_u-boot-env-y		:= u-boot-env.o
diff --git a/drivers/nvmem/u-boot-env.c b/drivers/nvmem/u-boot-env.c
new file mode 100644
index 000000000000..a932b3d3c63b
--- /dev/null
+++ b/drivers/nvmem/u-boot-env.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+#include <linux/crc32.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_DEFAULT,
+	U_BOOT_FORMAT_BRCM,
+};
+
+struct u_boot_env {
+	struct device *dev;
+	enum u_boot_env_format format;
+	struct mtd_info *mtd;
+	size_t offset;
+	size_t size;
+	struct nvmem_cell_info *cells;
+	int ncells;
+};
+
+struct u_boot_env_image {
+	__le32 crc32;
+	uint8_t data[0];
+} __packed;
+
+struct u_boot_brcm_header {
+	__le32 unk;
+	__le32 len;
+} __packed;
+
+static int u_boot_env_read(void *context, unsigned int offset, void *val,
+			   size_t bytes)
+{
+	struct u_boot_env *priv = context;
+	struct device *dev = priv->dev;
+	size_t bytes_read;
+	int err;
+
+	err = mtd_read(priv->mtd, priv->offset + offset, bytes, &bytes_read, val);
+	if (err && !mtd_is_bitflip(err)) {
+		dev_err(dev, "Failed to read from mtd: %d\n", err);
+		return err;
+	}
+
+	if (bytes_read != bytes) {
+		dev_err(dev, "Failed to read %zd bytes\n", bytes);
+		return err;
+	}
+
+	return 0;
+}
+
+static int u_boot_env_add_cells(struct u_boot_env *priv, size_t data_offset,
+				uint8_t *data, size_t len)
+{
+	struct device *dev = priv->dev;
+	char *var, *value, *eq;
+	int idx;
+
+	priv->ncells = 0;
+	for (var = data; var < (char *)data + len && *var; var += strlen(var) + 1)
+		priv->ncells++;
+
+	priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
+	if (!priv->cells)
+		return -ENOMEM;
+
+	for (var = data, idx = 0;
+	     var < (char *)data + len && *var;
+	     var = value + strlen(value) + 1, idx++) {
+		eq = strchr(var, '=');
+		if (!eq)
+			break;
+		*eq = '\0';
+		value = eq + 1;
+
+		priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
+		if (!priv->cells[idx].name)
+			return -ENOMEM;
+		priv->cells[idx].offset = data_offset + value - (char *)data;
+		priv->cells[idx].bytes = strlen(value);
+	}
+
+	if (WARN_ON(idx != priv->ncells))
+		priv->ncells = idx;
+
+	return 0;
+}
+
+static int u_boot_env_parse(struct u_boot_env *priv)
+{
+	struct device *dev = priv->dev;
+	struct u_boot_env_image *image;
+	size_t image_offset;
+	size_t image_len;
+	uint32_t crc32;
+	size_t bytes;
+	uint8_t *buf;
+	int err;
+
+	image_offset = 0;
+	image_len = priv->size;
+	if (priv->format == U_BOOT_FORMAT_BRCM) {
+		struct u_boot_brcm_header header;
+
+		err = mtd_read(priv->mtd, priv->offset, sizeof(header), &bytes,
+			       (uint8_t *)&header);
+		if (err && !mtd_is_bitflip(err)) {
+			dev_err(dev, "Failed to read from mtd: %d\n", err);
+			return err;
+		}
+
+		image_offset = sizeof(header);
+		image_len = le32_to_cpu(header.len);
+	}
+	dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
+
+	buf = kcalloc(1, image_len, GFP_KERNEL);
+	if (!buf) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	image = (struct u_boot_env_image *)buf;
+
+	err = mtd_read(priv->mtd, priv->offset + image_offset, image_len, &bytes, buf);
+	if (err && !mtd_is_bitflip(err)) {
+		dev_err(dev, "Failed to read from mtd: %d\n", err);
+		goto err_kfree;
+	}
+
+	crc32 = crc32(~0, buf + 4, image_len - 4) ^ ~0L;
+	if (crc32 != le32_to_cpu(image->crc32)) {
+		dev_err(dev, "Invalid calculated CRC32: 0x%08x\n", crc32);
+		err = -EINVAL;
+		goto err_kfree;
+	}
+
+	buf[image_len - 1] = '\0';
+	err = u_boot_env_add_cells(priv, image_offset + sizeof(*image),
+				   buf + sizeof(*image),
+				   image_len - sizeof(*image));
+	if (err)
+		dev_err(dev, "Failed to add cells: %d\n", err);
+
+err_kfree:
+	kfree(buf);
+err_out:
+	return err;
+}
+
+static const struct of_device_id u_boot_env_of_match_table[] = {
+	{ .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_DEFAULT, },
+	{ .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BRCM, },
+	{},
+};
+
+static int u_boot_env_probe(struct platform_device *pdev)
+{
+	struct nvmem_config config = {
+		.name = "u-boot-env",
+		.reg_read = u_boot_env_read,
+	};
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct of_device_id *of_id;
+	struct u_boot_env *priv;
+	const char *label;
+	int err;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	priv->dev = dev;
+
+	of_id = of_match_device(u_boot_env_of_match_table, dev);
+	if (!of_id)
+		return -EINVAL;
+	priv->format = (uintptr_t)of_id->data;
+
+	if (of_property_read_u32(np, "reg", &priv->offset) ||
+	    of_property_read_u32_index(np, "reg", 1, &priv->size)) {
+		dev_err(dev, "Failed to read \"reg\" property\n");
+		return -EINVAL;
+	}
+
+	label = of_get_property(np->parent, "label", NULL);
+	if (!label)
+		label = np->parent->name;
+
+	priv->mtd = get_mtd_device_nm(label);
+	if (IS_ERR(priv->mtd)) {
+		dev_err(dev, "Failed to find \"%s\" MTD device: %ld\n", label, PTR_ERR(priv->mtd));
+		return PTR_ERR(priv->mtd);
+	}
+
+	err = u_boot_env_parse(priv);
+	if (err)
+		return err;
+
+	config.dev = dev;
+	config.cells = priv->cells;
+	config.ncells = priv->ncells;
+	config.priv = priv;
+	config.size = priv->size;
+
+	return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
+}
+
+static struct platform_driver u_boot_env_driver = {
+	.probe = u_boot_env_probe,
+	.driver = {
+		.name = "u_boot_env",
+		.of_match_table = u_boot_env_of_match_table,
+	},
+};
+
+static int __init u_boot_env_init(void)
+{
+	return platform_driver_register(&u_boot_env_driver);
+}
+
+subsys_initcall_sync(u_boot_env_init);
+
+MODULE_AUTHOR("Rafał Miłecki");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
-- 
2.31.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] dt-bindings: nvmem: add U-Boot environment variables binding
  2021-12-22 19:23   ` Rafał Miłecki
@ 2021-12-23 16:24     ` Pratyush Yadav
  -1 siblings, 0 replies; 11+ messages in thread
From: Pratyush Yadav @ 2021-12-23 16:24 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, devicetree,
	linux-kernel, linux-mtd, Rafał Miłecki

On 22/12/21 08:23PM, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This binding allows describing a (part of) MTD device (partition) that
> contains a block with environment variables. Operating system usually
> needs to parse that block to read variables values that may affect
> booting process & device configuration.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
>  .../devicetree/bindings/nvmem/u-boot,env.yaml | 56 +++++++++++++++++++
>  MAINTAINERS                                   |  5 ++
>  2 files changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> new file mode 100644
> index 000000000000..0f808868fff3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> +
> +properties:
> +  compatible:
> +    enum:
> +      - u,boot,env

Typo? In patch 3 you match u-boot,env.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] dt-bindings: nvmem: add U-Boot environment variables binding
@ 2021-12-23 16:24     ` Pratyush Yadav
  0 siblings, 0 replies; 11+ messages in thread
From: Pratyush Yadav @ 2021-12-23 16:24 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: Srinivas Kandagatla, Rob Herring, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, devicetree,
	linux-kernel, linux-mtd, Rafał Miłecki

On 22/12/21 08:23PM, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This binding allows describing a (part of) MTD device (partition) that
> contains a block with environment variables. Operating system usually
> needs to parse that block to read variables values that may affect
> booting process & device configuration.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
>  .../devicetree/bindings/nvmem/u-boot,env.yaml | 56 +++++++++++++++++++
>  MAINTAINERS                                   |  5 ++
>  2 files changed, 61 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> 
> diff --git a/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> new file mode 100644
> index 000000000000..0f808868fff3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
> +
> +properties:
> +  compatible:
> +    enum:
> +      - u,boot,env

Typo? In patch 3 you match u-boot,env.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] nvmem: add driver handling U-Boot environment variables
  2021-12-22 19:23   ` Rafał Miłecki
  (?)
@ 2021-12-27  5:13     ` kernel test robot
  -1 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2021-12-27  5:13 UTC (permalink / raw)
  To: Rafał Miłecki, Srinivas Kandagatla, Rob Herring,
	Miquel Raynal, Richard Weinberger, Vignesh Raghavendra
  Cc: llvm, kbuild-all, devicetree, linux-kernel, linux-mtd,
	Rafał Miłecki

Hi "Rafał,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on mtd/mtd/next mtd/mtd/fixes linus/master v5.16-rc7 next-20211224]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: riscv-randconfig-c006-20211227 (https://download.01.org/0day-ci/archive/20211227/202112271307.07oSwFJV-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 511726c64d3b6cca66f7c54d457d586aa3129f67)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/43acf8c3e5ac48785826453744a925ff149b1d60
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
        git checkout 43acf8c3e5ac48785826453744a925ff149b1d60
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/nvmem/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

>> drivers/nvmem/u-boot-env.c:126:46: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                   ~~~~                ^~~~~~~~~~~~
                                   %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
   drivers/nvmem/u-boot-env.c:126:60: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                              ~~~~                   ^~~~~~~~~
                                              %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
>> drivers/nvmem/u-boot-env.c:190:38: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
           if (of_property_read_u32(np, "reg", &priv->offset) ||
                                               ^~~~~~~~~~~~~
   include/linux/of.h:1255:17: note: passing argument to parameter 'out_value' here
                                          u32 *out_value)
                                               ^
   drivers/nvmem/u-boot-env.c:191:47: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
               of_property_read_u32_index(np, "reg", 1, &priv->size)) {
                                                        ^~~~~~~~~~~
   include/linux/of.h:311:28: note: passing argument to parameter 'out_value' here
                                          u32 index, u32 *out_value);
                                                          ^
   2 warnings and 2 errors generated.


vim +190 drivers/nvmem/u-boot-env.c

    99	
   100	static int u_boot_env_parse(struct u_boot_env *priv)
   101	{
   102		struct device *dev = priv->dev;
   103		struct u_boot_env_image *image;
   104		size_t image_offset;
   105		size_t image_len;
   106		uint32_t crc32;
   107		size_t bytes;
   108		uint8_t *buf;
   109		int err;
   110	
   111		image_offset = 0;
   112		image_len = priv->size;
   113		if (priv->format == U_BOOT_FORMAT_BRCM) {
   114			struct u_boot_brcm_header header;
   115	
   116			err = mtd_read(priv->mtd, priv->offset, sizeof(header), &bytes,
   117				       (uint8_t *)&header);
   118			if (err && !mtd_is_bitflip(err)) {
   119				dev_err(dev, "Failed to read from mtd: %d\n", err);
   120				return err;
   121			}
   122	
   123			image_offset = sizeof(header);
   124			image_len = le32_to_cpu(header.len);
   125		}
 > 126		dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
   127	
   128		buf = kcalloc(1, image_len, GFP_KERNEL);
   129		if (!buf) {
   130			err = -ENOMEM;
   131			goto err_out;
   132		}
   133		image = (struct u_boot_env_image *)buf;
   134	
   135		err = mtd_read(priv->mtd, priv->offset + image_offset, image_len, &bytes, buf);
   136		if (err && !mtd_is_bitflip(err)) {
   137			dev_err(dev, "Failed to read from mtd: %d\n", err);
   138			goto err_kfree;
   139		}
   140	
   141		crc32 = crc32(~0, buf + 4, image_len - 4) ^ ~0L;
   142		if (crc32 != le32_to_cpu(image->crc32)) {
   143			dev_err(dev, "Invalid calculated CRC32: 0x%08x\n", crc32);
   144			err = -EINVAL;
   145			goto err_kfree;
   146		}
   147	
   148		buf[image_len - 1] = '\0';
   149		err = u_boot_env_add_cells(priv, image_offset + sizeof(*image),
   150					   buf + sizeof(*image),
   151					   image_len - sizeof(*image));
   152		if (err)
   153			dev_err(dev, "Failed to add cells: %d\n", err);
   154	
   155	err_kfree:
   156		kfree(buf);
   157	err_out:
   158		return err;
   159	}
   160	
   161	static const struct of_device_id u_boot_env_of_match_table[] = {
   162		{ .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_DEFAULT, },
   163		{ .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BRCM, },
   164		{},
   165	};
   166	
   167	static int u_boot_env_probe(struct platform_device *pdev)
   168	{
   169		struct nvmem_config config = {
   170			.name = "u-boot-env",
   171			.reg_read = u_boot_env_read,
   172		};
   173		struct device *dev = &pdev->dev;
   174		struct device_node *np = dev->of_node;
   175		const struct of_device_id *of_id;
   176		struct u_boot_env *priv;
   177		const char *label;
   178		int err;
   179	
   180		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
   181		if (!priv)
   182			return -ENOMEM;
   183		priv->dev = dev;
   184	
   185		of_id = of_match_device(u_boot_env_of_match_table, dev);
   186		if (!of_id)
   187			return -EINVAL;
   188		priv->format = (uintptr_t)of_id->data;
   189	
 > 190		if (of_property_read_u32(np, "reg", &priv->offset) ||
   191		    of_property_read_u32_index(np, "reg", 1, &priv->size)) {
   192			dev_err(dev, "Failed to read \"reg\" property\n");
   193			return -EINVAL;
   194		}
   195	
   196		label = of_get_property(np->parent, "label", NULL);
   197		if (!label)
   198			label = np->parent->name;
   199	
   200		priv->mtd = get_mtd_device_nm(label);
   201		if (IS_ERR(priv->mtd)) {
   202			dev_err(dev, "Failed to find \"%s\" MTD device: %ld\n", label, PTR_ERR(priv->mtd));
   203			return PTR_ERR(priv->mtd);
   204		}
   205	
   206		err = u_boot_env_parse(priv);
   207		if (err)
   208			return err;
   209	
   210		config.dev = dev;
   211		config.cells = priv->cells;
   212		config.ncells = priv->ncells;
   213		config.priv = priv;
   214		config.size = priv->size;
   215	
   216		return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
   217	}
   218	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] nvmem: add driver handling U-Boot environment variables
@ 2021-12-27  5:13     ` kernel test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2021-12-27  5:13 UTC (permalink / raw)
  To: Rafał Miłecki, Srinivas Kandagatla, Rob Herring,
	Miquel Raynal, Richard Weinberger, Vignesh Raghavendra
  Cc: llvm, kbuild-all, devicetree, linux-kernel, linux-mtd,
	Rafał Miłecki

Hi "Rafał,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on mtd/mtd/next mtd/mtd/fixes linus/master v5.16-rc7 next-20211224]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: riscv-randconfig-c006-20211227 (https://download.01.org/0day-ci/archive/20211227/202112271307.07oSwFJV-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 511726c64d3b6cca66f7c54d457d586aa3129f67)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/43acf8c3e5ac48785826453744a925ff149b1d60
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
        git checkout 43acf8c3e5ac48785826453744a925ff149b1d60
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/nvmem/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

>> drivers/nvmem/u-boot-env.c:126:46: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                   ~~~~                ^~~~~~~~~~~~
                                   %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
   drivers/nvmem/u-boot-env.c:126:60: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                              ~~~~                   ^~~~~~~~~
                                              %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
>> drivers/nvmem/u-boot-env.c:190:38: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
           if (of_property_read_u32(np, "reg", &priv->offset) ||
                                               ^~~~~~~~~~~~~
   include/linux/of.h:1255:17: note: passing argument to parameter 'out_value' here
                                          u32 *out_value)
                                               ^
   drivers/nvmem/u-boot-env.c:191:47: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
               of_property_read_u32_index(np, "reg", 1, &priv->size)) {
                                                        ^~~~~~~~~~~
   include/linux/of.h:311:28: note: passing argument to parameter 'out_value' here
                                          u32 index, u32 *out_value);
                                                          ^
   2 warnings and 2 errors generated.


vim +190 drivers/nvmem/u-boot-env.c

    99	
   100	static int u_boot_env_parse(struct u_boot_env *priv)
   101	{
   102		struct device *dev = priv->dev;
   103		struct u_boot_env_image *image;
   104		size_t image_offset;
   105		size_t image_len;
   106		uint32_t crc32;
   107		size_t bytes;
   108		uint8_t *buf;
   109		int err;
   110	
   111		image_offset = 0;
   112		image_len = priv->size;
   113		if (priv->format == U_BOOT_FORMAT_BRCM) {
   114			struct u_boot_brcm_header header;
   115	
   116			err = mtd_read(priv->mtd, priv->offset, sizeof(header), &bytes,
   117				       (uint8_t *)&header);
   118			if (err && !mtd_is_bitflip(err)) {
   119				dev_err(dev, "Failed to read from mtd: %d\n", err);
   120				return err;
   121			}
   122	
   123			image_offset = sizeof(header);
   124			image_len = le32_to_cpu(header.len);
   125		}
 > 126		dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
   127	
   128		buf = kcalloc(1, image_len, GFP_KERNEL);
   129		if (!buf) {
   130			err = -ENOMEM;
   131			goto err_out;
   132		}
   133		image = (struct u_boot_env_image *)buf;
   134	
   135		err = mtd_read(priv->mtd, priv->offset + image_offset, image_len, &bytes, buf);
   136		if (err && !mtd_is_bitflip(err)) {
   137			dev_err(dev, "Failed to read from mtd: %d\n", err);
   138			goto err_kfree;
   139		}
   140	
   141		crc32 = crc32(~0, buf + 4, image_len - 4) ^ ~0L;
   142		if (crc32 != le32_to_cpu(image->crc32)) {
   143			dev_err(dev, "Invalid calculated CRC32: 0x%08x\n", crc32);
   144			err = -EINVAL;
   145			goto err_kfree;
   146		}
   147	
   148		buf[image_len - 1] = '\0';
   149		err = u_boot_env_add_cells(priv, image_offset + sizeof(*image),
   150					   buf + sizeof(*image),
   151					   image_len - sizeof(*image));
   152		if (err)
   153			dev_err(dev, "Failed to add cells: %d\n", err);
   154	
   155	err_kfree:
   156		kfree(buf);
   157	err_out:
   158		return err;
   159	}
   160	
   161	static const struct of_device_id u_boot_env_of_match_table[] = {
   162		{ .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_DEFAULT, },
   163		{ .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BRCM, },
   164		{},
   165	};
   166	
   167	static int u_boot_env_probe(struct platform_device *pdev)
   168	{
   169		struct nvmem_config config = {
   170			.name = "u-boot-env",
   171			.reg_read = u_boot_env_read,
   172		};
   173		struct device *dev = &pdev->dev;
   174		struct device_node *np = dev->of_node;
   175		const struct of_device_id *of_id;
   176		struct u_boot_env *priv;
   177		const char *label;
   178		int err;
   179	
   180		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
   181		if (!priv)
   182			return -ENOMEM;
   183		priv->dev = dev;
   184	
   185		of_id = of_match_device(u_boot_env_of_match_table, dev);
   186		if (!of_id)
   187			return -EINVAL;
   188		priv->format = (uintptr_t)of_id->data;
   189	
 > 190		if (of_property_read_u32(np, "reg", &priv->offset) ||
   191		    of_property_read_u32_index(np, "reg", 1, &priv->size)) {
   192			dev_err(dev, "Failed to read \"reg\" property\n");
   193			return -EINVAL;
   194		}
   195	
   196		label = of_get_property(np->parent, "label", NULL);
   197		if (!label)
   198			label = np->parent->name;
   199	
   200		priv->mtd = get_mtd_device_nm(label);
   201		if (IS_ERR(priv->mtd)) {
   202			dev_err(dev, "Failed to find \"%s\" MTD device: %ld\n", label, PTR_ERR(priv->mtd));
   203			return PTR_ERR(priv->mtd);
   204		}
   205	
   206		err = u_boot_env_parse(priv);
   207		if (err)
   208			return err;
   209	
   210		config.dev = dev;
   211		config.cells = priv->cells;
   212		config.ncells = priv->ncells;
   213		config.priv = priv;
   214		config.size = priv->size;
   215	
   216		return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
   217	}
   218	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] nvmem: add driver handling U-Boot environment variables
@ 2021-12-27  5:13     ` kernel test robot
  0 siblings, 0 replies; 11+ messages in thread
From: kernel test robot @ 2021-12-27  5:13 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 8750 bytes --]

Hi "Rafał,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on mtd/mtd/next mtd/mtd/fixes linus/master v5.16-rc7 next-20211224]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: riscv-randconfig-c006-20211227 (https://download.01.org/0day-ci/archive/20211227/202112271307.07oSwFJV-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 511726c64d3b6cca66f7c54d457d586aa3129f67)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/43acf8c3e5ac48785826453744a925ff149b1d60
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Rafa-Mi-ecki/mtd-core-call-devm_of_platform_populate-for-MTD-devices/20211223-032456
        git checkout 43acf8c3e5ac48785826453744a925ff149b1d60
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/nvmem/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

>> drivers/nvmem/u-boot-env.c:126:46: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                   ~~~~                ^~~~~~~~~~~~
                                   %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
   drivers/nvmem/u-boot-env.c:126:60: warning: format specifies type 'unsigned int' but the argument has type 'size_t' (aka 'unsigned long') [-Wformat]
           dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
                                              ~~~~                   ^~~~~~~~~
                                              %08lx
   include/linux/dev_printk.h:150:67: note: expanded from macro 'dev_info'
           dev_printk_index_wrap(_dev_info, KERN_INFO, dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                                    ~~~     ^~~~~~~~~~~
   include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap'
                   _p_func(dev, fmt, ##__VA_ARGS__);                       \
                                ~~~    ^~~~~~~~~~~
>> drivers/nvmem/u-boot-env.c:190:38: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
           if (of_property_read_u32(np, "reg", &priv->offset) ||
                                               ^~~~~~~~~~~~~
   include/linux/of.h:1255:17: note: passing argument to parameter 'out_value' here
                                          u32 *out_value)
                                               ^
   drivers/nvmem/u-boot-env.c:191:47: error: incompatible pointer types passing 'size_t *' (aka 'unsigned long *') to parameter of type 'u32 *' (aka 'unsigned int *') [-Werror,-Wincompatible-pointer-types]
               of_property_read_u32_index(np, "reg", 1, &priv->size)) {
                                                        ^~~~~~~~~~~
   include/linux/of.h:311:28: note: passing argument to parameter 'out_value' here
                                          u32 index, u32 *out_value);
                                                          ^
   2 warnings and 2 errors generated.


vim +190 drivers/nvmem/u-boot-env.c

    99	
   100	static int u_boot_env_parse(struct u_boot_env *priv)
   101	{
   102		struct device *dev = priv->dev;
   103		struct u_boot_env_image *image;
   104		size_t image_offset;
   105		size_t image_len;
   106		uint32_t crc32;
   107		size_t bytes;
   108		uint8_t *buf;
   109		int err;
   110	
   111		image_offset = 0;
   112		image_len = priv->size;
   113		if (priv->format == U_BOOT_FORMAT_BRCM) {
   114			struct u_boot_brcm_header header;
   115	
   116			err = mtd_read(priv->mtd, priv->offset, sizeof(header), &bytes,
   117				       (uint8_t *)&header);
   118			if (err && !mtd_is_bitflip(err)) {
   119				dev_err(dev, "Failed to read from mtd: %d\n", err);
   120				return err;
   121			}
   122	
   123			image_offset = sizeof(header);
   124			image_len = le32_to_cpu(header.len);
   125		}
 > 126		dev_info(dev, "offset:0x%08x len:0x%08x\n", image_offset, image_len);
   127	
   128		buf = kcalloc(1, image_len, GFP_KERNEL);
   129		if (!buf) {
   130			err = -ENOMEM;
   131			goto err_out;
   132		}
   133		image = (struct u_boot_env_image *)buf;
   134	
   135		err = mtd_read(priv->mtd, priv->offset + image_offset, image_len, &bytes, buf);
   136		if (err && !mtd_is_bitflip(err)) {
   137			dev_err(dev, "Failed to read from mtd: %d\n", err);
   138			goto err_kfree;
   139		}
   140	
   141		crc32 = crc32(~0, buf + 4, image_len - 4) ^ ~0L;
   142		if (crc32 != le32_to_cpu(image->crc32)) {
   143			dev_err(dev, "Invalid calculated CRC32: 0x%08x\n", crc32);
   144			err = -EINVAL;
   145			goto err_kfree;
   146		}
   147	
   148		buf[image_len - 1] = '\0';
   149		err = u_boot_env_add_cells(priv, image_offset + sizeof(*image),
   150					   buf + sizeof(*image),
   151					   image_len - sizeof(*image));
   152		if (err)
   153			dev_err(dev, "Failed to add cells: %d\n", err);
   154	
   155	err_kfree:
   156		kfree(buf);
   157	err_out:
   158		return err;
   159	}
   160	
   161	static const struct of_device_id u_boot_env_of_match_table[] = {
   162		{ .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_DEFAULT, },
   163		{ .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BRCM, },
   164		{},
   165	};
   166	
   167	static int u_boot_env_probe(struct platform_device *pdev)
   168	{
   169		struct nvmem_config config = {
   170			.name = "u-boot-env",
   171			.reg_read = u_boot_env_read,
   172		};
   173		struct device *dev = &pdev->dev;
   174		struct device_node *np = dev->of_node;
   175		const struct of_device_id *of_id;
   176		struct u_boot_env *priv;
   177		const char *label;
   178		int err;
   179	
   180		priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
   181		if (!priv)
   182			return -ENOMEM;
   183		priv->dev = dev;
   184	
   185		of_id = of_match_device(u_boot_env_of_match_table, dev);
   186		if (!of_id)
   187			return -EINVAL;
   188		priv->format = (uintptr_t)of_id->data;
   189	
 > 190		if (of_property_read_u32(np, "reg", &priv->offset) ||
   191		    of_property_read_u32_index(np, "reg", 1, &priv->size)) {
   192			dev_err(dev, "Failed to read \"reg\" property\n");
   193			return -EINVAL;
   194		}
   195	
   196		label = of_get_property(np->parent, "label", NULL);
   197		if (!label)
   198			label = np->parent->name;
   199	
   200		priv->mtd = get_mtd_device_nm(label);
   201		if (IS_ERR(priv->mtd)) {
   202			dev_err(dev, "Failed to find \"%s\" MTD device: %ld\n", label, PTR_ERR(priv->mtd));
   203			return PTR_ERR(priv->mtd);
   204		}
   205	
   206		err = u_boot_env_parse(priv);
   207		if (err)
   208			return err;
   209	
   210		config.dev = dev;
   211		config.cells = priv->cells;
   212		config.ncells = priv->ncells;
   213		config.priv = priv;
   214		config.size = priv->size;
   215	
   216		return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
   217	}
   218	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-12-27  5:15 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-22 19:23 [PATCH 1/3] mtd: core: call devm_of_platform_populate() for MTD devices Rafał Miłecki
2021-12-22 19:23 ` Rafał Miłecki
2021-12-22 19:23 ` [PATCH 2/3] dt-bindings: nvmem: add U-Boot environment variables binding Rafał Miłecki
2021-12-22 19:23   ` Rafał Miłecki
2021-12-23 16:24   ` Pratyush Yadav
2021-12-23 16:24     ` Pratyush Yadav
2021-12-22 19:23 ` [PATCH 3/3] nvmem: add driver handling U-Boot environment variables Rafał Miłecki
2021-12-22 19:23   ` Rafał Miłecki
2021-12-27  5:13   ` kernel test robot
2021-12-27  5:13     ` kernel test robot
2021-12-27  5:13     ` kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.