kernel: 5.10: update nvmem subsystem to the 5.15 state
authorRafał Miłecki <rafal@milecki.pl>
Fri, 6 Jan 2023 13:03:12 +0000 (14:03 +0100)
committerRafał Miłecki <rafal@milecki.pl>
Fri, 6 Jan 2023 13:34:37 +0000 (14:34 +0100)
This allows cleanly backporting more recent stuff that's important for
OpenWrt.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
39 files changed:
target/linux/bcm53xx/patches-5.10/080-v5.13-0002-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch [deleted file]
target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/801-v5.11-0002-nvmem-qfprom-Don-t-touch-certain-fuses.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/801-v5.11-0003-nvmem-imx-ocotp-add-support-for-the-unaliged-word-co.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/801-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch [deleted file]
target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch [deleted file]
target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch [deleted file]
target/linux/generic/backport-5.10/802-v5.12-0002-nvmem-imx-iim-Use-of_device_get_match_data.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/802-v5.12-0003-nvmem-Add-driver-to-expose-reserved-memory-as-nvmem.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/802-v5.12-0005-nvmem-Kconfig-Correct-typo-in-NVMEM_RMEM.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/802-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch [deleted file]
target/linux/generic/backport-5.10/803-v5.13-0001-nvmem-convert-comma-to-semicolon.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v5.13-0003-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v5.13-0004-nvmem-core-Add-functions-to-make-number-reading-easy.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v5.13-0005-nvmem-core-Fix-unintentional-sign-extension-issue.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v5.13-0006-nvmem-rmem-fix-undefined-reference-to-memremap.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v5.13-0007-nvmem-qfprom-Add-support-for-fuse-blowing-on-sc7280.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/803-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch [deleted file]
target/linux/generic/backport-5.10/803-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch [deleted file]
target/linux/generic/backport-5.10/803-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch [deleted file]
target/linux/generic/backport-5.10/804-v5.14-0001-nvmem-core-allow-specifying-of_node.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0002-nvmem-sprd-Fix-an-error-message.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0003-nvmem-sunxi_sid-Set-type-to-OTP.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0004-nvmem-qfprom-minor-nit-fixes.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0005-nvmem-core-constify-nvmem_cell_read_variable_common-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0006-nvmem-qfprom-Improve-the-comment-about-regulator-set.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/804-v5.14-0007-nvmem-add-NVMEM_TYPE_FRAM.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/805-v5.15-0002-nvmem-qfprom-sc7280-Handle-the-additional-power-doma.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/805-v5.15-0003-nvmem-core-fix-error-handling-while-validating-keepo.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/805-v5.15-0004-nvmem-nintendo-otp-Add-new-driver-for-the-Wii-and-Wi.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/805-v5.15-0005-nvmem-NVMEM_NINTENDO_OTP-should-depend-on-WII.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/823-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/823-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/823-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/824-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/825-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/825-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch [new file with mode: 0644]
target/linux/generic/backport-5.10/825-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch [new file with mode: 0644]
target/linux/generic/config-5.10

diff --git a/target/linux/bcm53xx/patches-5.10/080-v5.13-0002-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch b/target/linux/bcm53xx/patches-5.10/080-v5.13-0002-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch
deleted file mode 100644 (file)
index 3a8940b..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From b152bbeb0282bfcf6f91d0d5befd7582c1c3fc23 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 5 Mar 2021 19:32:36 +0100
-Subject: [PATCH] nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This driver provides access to Broadcom's NVRAM.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/Kconfig      |  9 +++++
- drivers/nvmem/Makefile     |  2 +
- drivers/nvmem/brcm_nvram.c | 78 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 89 insertions(+)
- create mode 100644 drivers/nvmem/brcm_nvram.c
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -283,4 +283,13 @@ config NVMEM_U_BOOT_ENV
-         If compiled as module it will be called nvmem_u-boot-env.
-+
-+config NVMEM_BRCM_NVRAM
-+      tristate "Broadcom's NVRAM support"
-+      depends on ARCH_BCM_5301X || COMPILE_TEST
-+      depends on HAS_IOMEM
-+      help
-+        This driver provides support for Broadcom's NVRAM that can be accessed
-+        using I/O mapping.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -57,3 +57,5 @@ obj-$(CONFIG_SPRD_EFUSE)     += nvmem_sprd_e
- nvmem_sprd_efuse-y            := sprd-efuse.o
- obj-$(CONFIG_NVMEM_U_BOOT_ENV)        += nvmem_u-boot-env.o
- nvmem_u-boot-env-y            := u-boot-env.o
-+obj-$(CONFIG_NVMEM_BRCM_NVRAM)        += nvmem_brcm_nvram.o
-+nvmem_brcm_nvram-y            := brcm_nvram.o
---- /dev/null
-+++ b/drivers/nvmem/brcm_nvram.c
-@@ -0,0 +1,78 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
-+ */
-+
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/nvmem-provider.h>
-+#include <linux/platform_device.h>
-+
-+struct brcm_nvram {
-+      struct device *dev;
-+      void __iomem *base;
-+};
-+
-+static int brcm_nvram_read(void *context, unsigned int offset, void *val,
-+                         size_t bytes)
-+{
-+      struct brcm_nvram *priv = context;
-+      u8 *dst = val;
-+
-+      while (bytes--)
-+              *dst++ = readb(priv->base + offset++);
-+
-+      return 0;
-+}
-+
-+static int brcm_nvram_probe(struct platform_device *pdev)
-+{
-+      struct nvmem_config config = {
-+              .name = "brcm-nvram",
-+              .reg_read = brcm_nvram_read,
-+      };
-+      struct device *dev = &pdev->dev;
-+      struct resource *res;
-+      struct brcm_nvram *priv;
-+
-+      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+      priv->dev = dev;
-+
-+      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+      priv->base = devm_ioremap_resource(dev, res);
-+      if (IS_ERR(priv->base))
-+              return PTR_ERR(priv->base);
-+
-+      config.dev = dev;
-+      config.priv = priv;
-+      config.size = resource_size(res);
-+
-+      return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+}
-+
-+static const struct of_device_id brcm_nvram_of_match_table[] = {
-+      { .compatible = "brcm,nvram", },
-+      {},
-+};
-+
-+static struct platform_driver brcm_nvram_driver = {
-+      .probe = brcm_nvram_probe,
-+      .driver = {
-+              .name = "brcm_nvram",
-+              .of_match_table = brcm_nvram_of_match_table,
-+      },
-+};
-+
-+static int __init brcm_nvram_init(void)
-+{
-+      return platform_driver_register(&brcm_nvram_driver);
-+}
-+
-+subsys_initcall_sync(brcm_nvram_init);
-+
-+MODULE_AUTHOR("Rafał Miłecki");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
diff --git a/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch b/target/linux/generic/backport-5.10/801-v5.11-0001-nvmem-core-Add-support-for-keepout-regions.patch
new file mode 100644 (file)
index 0000000..6fe5032
--- /dev/null
@@ -0,0 +1,267 @@
+From fd3bb8f54a88107570334c156efb0c724a261003 Mon Sep 17 00:00:00 2001
+From: Evan Green <evgreen@chromium.org>
+Date: Fri, 27 Nov 2020 10:28:34 +0000
+Subject: [PATCH] nvmem: core: Add support for keepout regions
+
+Introduce support into the nvmem core for arrays of register ranges
+that should not result in actual device access. For these regions a
+constant byte (repeated) is returned instead on read, and writes are
+quietly ignored and returned as successful.
+
+This is useful for instance if certain efuse regions are protected
+from access by Linux because they contain secret info to another part
+of the system (like an integrated modem).
+
+Signed-off-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20201127102837.19366-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c           | 153 ++++++++++++++++++++++++++++++++-
+ include/linux/nvmem-provider.h |  17 ++++
+ 2 files changed, 166 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -34,6 +34,8 @@ struct nvmem_device {
+       struct bin_attribute    eeprom;
+       struct device           *base_dev;
+       struct list_head        cells;
++      const struct nvmem_keepout *keepout;
++      unsigned int            nkeepout;
+       nvmem_reg_read_t        reg_read;
+       nvmem_reg_write_t       reg_write;
+       struct gpio_desc        *wp_gpio;
+@@ -66,8 +68,8 @@ static LIST_HEAD(nvmem_lookup_list);
+ static BLOCKING_NOTIFIER_HEAD(nvmem_notifier);
+-static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
+-                        void *val, size_t bytes)
++static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
++                          void *val, size_t bytes)
+ {
+       if (nvmem->reg_read)
+               return nvmem->reg_read(nvmem->priv, offset, val, bytes);
+@@ -75,8 +77,8 @@ static int nvmem_reg_read(struct nvmem_d
+       return -EINVAL;
+ }
+-static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
+-                         void *val, size_t bytes)
++static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
++                           void *val, size_t bytes)
+ {
+       int ret;
+@@ -90,6 +92,88 @@ static int nvmem_reg_write(struct nvmem_
+       return -EINVAL;
+ }
++static int nvmem_access_with_keepouts(struct nvmem_device *nvmem,
++                                    unsigned int offset, void *val,
++                                    size_t bytes, int write)
++{
++
++      unsigned int end = offset + bytes;
++      unsigned int kend, ksize;
++      const struct nvmem_keepout *keepout = nvmem->keepout;
++      const struct nvmem_keepout *keepoutend = keepout + nvmem->nkeepout;
++      int rc;
++
++      /*
++       * Skip all keepouts before the range being accessed.
++       * Keepouts are sorted.
++       */
++      while ((keepout < keepoutend) && (keepout->end <= offset))
++              keepout++;
++
++      while ((offset < end) && (keepout < keepoutend)) {
++              /* Access the valid portion before the keepout. */
++              if (offset < keepout->start) {
++                      kend = min(end, keepout->start);
++                      ksize = kend - offset;
++                      if (write)
++                              rc = __nvmem_reg_write(nvmem, offset, val, ksize);
++                      else
++                              rc = __nvmem_reg_read(nvmem, offset, val, ksize);
++
++                      if (rc)
++                              return rc;
++
++                      offset += ksize;
++                      val += ksize;
++              }
++
++              /*
++               * Now we're aligned to the start of this keepout zone. Go
++               * through it.
++               */
++              kend = min(end, keepout->end);
++              ksize = kend - offset;
++              if (!write)
++                      memset(val, keepout->value, ksize);
++
++              val += ksize;
++              offset += ksize;
++              keepout++;
++      }
++
++      /*
++       * If we ran out of keepouts but there's still stuff to do, send it
++       * down directly
++       */
++      if (offset < end) {
++              ksize = end - offset;
++              if (write)
++                      return __nvmem_reg_write(nvmem, offset, val, ksize);
++              else
++                      return __nvmem_reg_read(nvmem, offset, val, ksize);
++      }
++
++      return 0;
++}
++
++static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
++                        void *val, size_t bytes)
++{
++      if (!nvmem->nkeepout)
++              return __nvmem_reg_read(nvmem, offset, val, bytes);
++
++      return nvmem_access_with_keepouts(nvmem, offset, val, bytes, false);
++}
++
++static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
++                         void *val, size_t bytes)
++{
++      if (!nvmem->nkeepout)
++              return __nvmem_reg_write(nvmem, offset, val, bytes);
++
++      return nvmem_access_with_keepouts(nvmem, offset, val, bytes, true);
++}
++
+ #ifdef CONFIG_NVMEM_SYSFS
+ static const char * const nvmem_type_str[] = {
+       [NVMEM_TYPE_UNKNOWN] = "Unknown",
+@@ -535,6 +619,59 @@ nvmem_find_cell_by_name(struct nvmem_dev
+       return cell;
+ }
++static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
++{
++      unsigned int cur = 0;
++      const struct nvmem_keepout *keepout = nvmem->keepout;
++      const struct nvmem_keepout *keepoutend = keepout + nvmem->nkeepout;
++
++      while (keepout < keepoutend) {
++              /* Ensure keepouts are sorted and don't overlap. */
++              if (keepout->start < cur) {
++                      dev_err(&nvmem->dev,
++                              "Keepout regions aren't sorted or overlap.\n");
++
++                      return -ERANGE;
++              }
++
++              if (keepout->end < keepout->start) {
++                      dev_err(&nvmem->dev,
++                              "Invalid keepout region.\n");
++
++                      return -EINVAL;
++              }
++
++              /*
++               * Validate keepouts (and holes between) don't violate
++               * word_size constraints.
++               */
++              if ((keepout->end - keepout->start < nvmem->word_size) ||
++                  ((keepout->start != cur) &&
++                   (keepout->start - cur < nvmem->word_size))) {
++
++                      dev_err(&nvmem->dev,
++                              "Keepout regions violate word_size constraints.\n");
++
++                      return -ERANGE;
++              }
++
++              /* Validate keepouts don't violate stride (alignment). */
++              if (!IS_ALIGNED(keepout->start, nvmem->stride) ||
++                  !IS_ALIGNED(keepout->end, nvmem->stride)) {
++
++                      dev_err(&nvmem->dev,
++                              "Keepout regions violate stride.\n");
++
++                      return -EINVAL;
++              }
++
++              cur = keepout->end;
++              keepout++;
++      }
++
++      return 0;
++}
++
+ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+ {
+       struct device_node *parent, *child;
+@@ -655,6 +792,8 @@ struct nvmem_device *nvmem_register(cons
+       nvmem->type = config->type;
+       nvmem->reg_read = config->reg_read;
+       nvmem->reg_write = config->reg_write;
++      nvmem->keepout = config->keepout;
++      nvmem->nkeepout = config->nkeepout;
+       if (!config->no_of_node)
+               nvmem->dev.of_node = config->dev->of_node;
+@@ -679,6 +818,12 @@ struct nvmem_device *nvmem_register(cons
+       nvmem->dev.groups = nvmem_dev_groups;
+ #endif
++      if (nvmem->nkeepout) {
++              rval = nvmem_validate_keepouts(nvmem);
++              if (rval)
++                      goto err_put_device;
++      }
++
+       dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
+       rval = device_register(&nvmem->dev);
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -31,6 +31,19 @@ enum nvmem_type {
+ #define NVMEM_DEVID_AUTO      (-2)
+ /**
++ * struct nvmem_keepout - NVMEM register keepout range.
++ *
++ * @start:    The first byte offset to avoid.
++ * @end:      One beyond the last byte offset to avoid.
++ * @value:    The byte to fill reads with for this region.
++ */
++struct nvmem_keepout {
++      unsigned int start;
++      unsigned int end;
++      unsigned char value;
++};
++
++/**
+  * struct nvmem_config - NVMEM device configuration
+  *
+  * @dev:      Parent device.
+@@ -39,6 +52,8 @@ enum nvmem_type {
+  * @owner:    Pointer to exporter module. Used for refcounting.
+  * @cells:    Optional array of pre-defined NVMEM cells.
+  * @ncells:   Number of elements in cells.
++ * @keepout:  Optional array of keepout ranges (sorted ascending by start).
++ * @nkeepout: Number of elements in the keepout array.
+  * @type:     Type of the nvmem storage
+  * @read_only:        Device is read-only.
+  * @root_only:        Device is accessibly to root only.
+@@ -66,6 +81,8 @@ struct nvmem_config {
+       struct gpio_desc        *wp_gpio;
+       const struct nvmem_cell_info    *cells;
+       int                     ncells;
++      const struct nvmem_keepout *keepout;
++      unsigned int            nkeepout;
+       enum nvmem_type         type;
+       bool                    read_only;
+       bool                    root_only;
diff --git a/target/linux/generic/backport-5.10/801-v5.11-0002-nvmem-qfprom-Don-t-touch-certain-fuses.patch b/target/linux/generic/backport-5.10/801-v5.11-0002-nvmem-qfprom-Don-t-touch-certain-fuses.patch
new file mode 100644 (file)
index 0000000..ae499e7
--- /dev/null
@@ -0,0 +1,87 @@
+From 044ee8f85267599a9b0112911f5c16d4548b4289 Mon Sep 17 00:00:00 2001
+From: Evan Green <evgreen@chromium.org>
+Date: Fri, 27 Nov 2020 10:28:36 +0000
+Subject: [PATCH] nvmem: qfprom: Don't touch certain fuses
+
+Some fuse ranges are protected by the XPU such that the AP cannot
+access them. Attempting to do so causes an SError. Use the newly
+introduced per-soc compatible string, and the newly introduced
+nvmem keepout support to attach the set of regions
+we should not access.
+
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Evan Green <evgreen@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20201127102837.19366-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qfprom.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -12,6 +12,7 @@
+ #include <linux/mod_devicetable.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/platform_device.h>
++#include <linux/property.h>
+ #include <linux/regulator/consumer.h>
+ /* Blow timer clock frequency in Mhz */
+@@ -89,6 +90,28 @@ struct qfprom_touched_values {
+ };
+ /**
++ * struct qfprom_soc_compatible_data - Data matched against the SoC
++ * compatible string.
++ *
++ * @keepout: Array of keepout regions for this SoC.
++ * @nkeepout: Number of elements in the keepout array.
++ */
++struct qfprom_soc_compatible_data {
++      const struct nvmem_keepout *keepout;
++      unsigned int nkeepout;
++};
++
++static const struct nvmem_keepout sc7180_qfprom_keepout[] = {
++      {.start = 0x128, .end = 0x148},
++      {.start = 0x220, .end = 0x228}
++};
++
++static const struct qfprom_soc_compatible_data sc7180_qfprom = {
++      .keepout = sc7180_qfprom_keepout,
++      .nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
++};
++
++/**
+  * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
+  * @priv: Our driver data.
+  * @old:  The data that was stashed from before fuse blowing.
+@@ -302,6 +325,7 @@ static int qfprom_probe(struct platform_
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct nvmem_device *nvmem;
++      const struct qfprom_soc_compatible_data *soc_data;
+       struct qfprom_priv *priv;
+       int ret;
+@@ -320,6 +344,11 @@ static int qfprom_probe(struct platform_
+       econfig.priv = priv;
+       priv->dev = dev;
++      soc_data = device_get_match_data(dev);
++      if (soc_data) {
++              econfig.keepout = soc_data->keepout;
++              econfig.nkeepout = soc_data->nkeepout;
++      }
+       /*
+        * If more than one region is provided then the OS has the ability
+@@ -375,6 +404,7 @@ static int qfprom_probe(struct platform_
+ static const struct of_device_id qfprom_of_match[] = {
+       { .compatible = "qcom,qfprom",},
++      { .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
+       {/* sentinel */},
+ };
+ MODULE_DEVICE_TABLE(of, qfprom_of_match);
diff --git a/target/linux/generic/backport-5.10/801-v5.11-0003-nvmem-imx-ocotp-add-support-for-the-unaliged-word-co.patch b/target/linux/generic/backport-5.10/801-v5.11-0003-nvmem-imx-ocotp-add-support-for-the-unaliged-word-co.patch
new file mode 100644 (file)
index 0000000..0a05e0a
--- /dev/null
@@ -0,0 +1,105 @@
+From 3311bf18467272388039922a5e29c4925b291f73 Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Fri, 27 Nov 2020 10:28:37 +0000
+Subject: [PATCH] nvmem: imx-ocotp: add support for the unaliged word count
+
+When offset is not 4 bytes aligned, directly shift righty by 2 bits
+will cause reading out wrong data. Since imx ocotp only supports
+4 bytes reading once, we need handle offset is not 4 bytes aligned
+and enlarge the bytes to 4 bytes aligned. After reading finished,
+copy the needed data from buffer to caller and free buffer.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20201127102837.19366-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-ocotp.c | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+--- a/drivers/nvmem/imx-ocotp.c
++++ b/drivers/nvmem/imx-ocotp.c
+@@ -4,6 +4,8 @@
+  *
+  * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
+  *
++ * Copyright 2019 NXP
++ *
+  * Based on the barebox ocotp driver,
+  * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
+  *    Orex Computed Radiography
+@@ -158,22 +160,30 @@ static int imx_ocotp_read(void *context,
+ {
+       struct ocotp_priv *priv = context;
+       unsigned int count;
+-      u32 *buf = val;
++      u8 *buf, *p;
+       int i, ret;
+-      u32 index;
++      u32 index, num_bytes;
+       index = offset >> 2;
+-      count = bytes >> 2;
++      num_bytes = round_up((offset % 4) + bytes, 4);
++      count = num_bytes >> 2;
+       if (count > (priv->params->nregs - index))
+               count = priv->params->nregs - index;
++      p = kzalloc(num_bytes, GFP_KERNEL);
++      if (!p)
++              return -ENOMEM;
++
+       mutex_lock(&ocotp_mutex);
++      buf = p;
++
+       ret = clk_prepare_enable(priv->clk);
+       if (ret < 0) {
+               mutex_unlock(&ocotp_mutex);
+               dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
++              kfree(p);
+               return ret;
+       }
+@@ -184,7 +194,7 @@ static int imx_ocotp_read(void *context,
+       }
+       for (i = index; i < (index + count); i++) {
+-              *buf++ = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
++              *(u32 *)buf = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
+                              i * IMX_OCOTP_OFFSET_PER_WORD);
+               /* 47.3.1.2
+@@ -193,13 +203,21 @@ static int imx_ocotp_read(void *context,
+                * software before any new write, read or reload access can be
+                * issued
+                */
+-              if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL)
++              if (*((u32 *)buf) == IMX_OCOTP_READ_LOCKED_VAL)
+                       imx_ocotp_clr_err_if_set(priv);
++
++              buf += 4;
+       }
++      index = offset % 4;
++      memcpy(val, &p[index], bytes);
++
+ read_end:
+       clk_disable_unprepare(priv->clk);
+       mutex_unlock(&ocotp_mutex);
++
++      kfree(p);
++
+       return ret;
+ }
+@@ -447,7 +465,7 @@ static struct nvmem_config imx_ocotp_nvm
+       .name = "imx-ocotp",
+       .read_only = false,
+       .word_size = 4,
+-      .stride = 4,
++      .stride = 1,
+       .reg_read = imx_ocotp_read,
+       .reg_write = imx_ocotp_write,
+ };
diff --git a/target/linux/generic/backport-5.10/801-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.10/801-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch
deleted file mode 100644 (file)
index 1459d11..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-From f955dc14450695564926711cf9fa8e1d5d854302 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 15 Jun 2022 21:43:00 +0200
-Subject: [PATCH] nvmem: add driver handling U-Boot environment variables
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-U-Boot stores its setup as environment variables. It's a list of
-key-value pairs stored on flash device with a custom header.
-
-This commit adds an NVMEM driver that:
-1. Provides NVMEM access to environment vars binary data
-2. Extracts variables as NVMEM cells
-
-Current Linux's NVMEM sysfs API allows reading whole NVMEM data block.
-It can be used by user-space tools for reading U-Boot env vars block
-without the hassle of finding its location. Parsing will still need to
-be re-done there.
-
-Kernel-parsed NVMEM cells can be read however by Linux drivers. This may
-be useful for Ethernet drivers for reading device MAC address which is
-often stored as U-Boot env variable.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
-
---- a/drivers/nvmem/Kconfig
-+++ b/drivers/nvmem/Kconfig
-@@ -270,4 +270,17 @@ config SPRD_EFUSE
-         This driver can also be built as a module. If so, the module
-         will be called nvmem-sprd-efuse.
-+config NVMEM_U_BOOT_ENV
-+      tristate "U-Boot environment variables support"
-+      depends on OF && MTD
-+      select CRC32
-+      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.
-+
-+        Currently this drivers works only with env variables on top of MTD.
-+
-+        If compiled as module it will be called nvmem_u-boot-env.
-+
- endif
---- a/drivers/nvmem/Makefile
-+++ b/drivers/nvmem/Makefile
-@@ -55,3 +55,5 @@ obj-$(CONFIG_NVMEM_ZYNQMP)   += nvmem_zynq
- nvmem_zynqmp_nvmem-y          := zynqmp_nvmem.o
- obj-$(CONFIG_SPRD_EFUSE)      += nvmem_sprd_efuse.o
- nvmem_sprd_efuse-y            := sprd-efuse.o
-+obj-$(CONFIG_NVMEM_U_BOOT_ENV)        += nvmem_u-boot-env.o
-+nvmem_u-boot-env-y            := u-boot-env.o
---- /dev/null
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -0,0 +1,218 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Copyright (C) 2022 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_SINGLE,
-+      U_BOOT_FORMAT_REDUNDANT,
-+};
-+
-+struct u_boot_env {
-+      struct device *dev;
-+      enum u_boot_env_format format;
-+
-+      struct mtd_info *mtd;
-+
-+      /* Cells */
-+      struct nvmem_cell_info *cells;
-+      int ncells;
-+};
-+
-+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;
-+
-+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, 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 %zu bytes\n", bytes);
-+              return -EIO;
-+      }
-+
-+      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 device *dev = priv->dev;
-+      char *data = buf + data_offset;
-+      char *var, *value, *eq;
-+      int idx;
-+
-+      priv->ncells = 0;
-+      for (var = data; var < data + 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 < data + 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 - 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;
-+      size_t crc32_data_offset;
-+      size_t crc32_data_len;
-+      size_t crc32_offset;
-+      size_t data_offset;
-+      size_t data_len;
-+      uint32_t crc32;
-+      uint32_t calc;
-+      size_t bytes;
-+      uint8_t *buf;
-+      int err;
-+
-+      buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
-+      if (!buf) {
-+              err = -ENOMEM;
-+              goto err_out;
-+      }
-+
-+      err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
-+      if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
-+              dev_err(dev, "Failed to read from mtd: %d\n", err);
-+              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, mark);
-+              data_offset = offsetof(struct u_boot_env_image_redundant, data);
-+              break;
-+      }
-+      crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
-+      crc32_data_len = priv->mtd->size - crc32_data_offset;
-+      data_len = priv->mtd->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[priv->mtd->size - 1] = '\0';
-+      err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
-+      if (err)
-+              dev_err(dev, "Failed to add cells: %d\n", err);
-+
-+err_kfree:
-+      kfree(buf);
-+err_out:
-+      return err;
-+}
-+
-+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;
-+      struct u_boot_env *priv;
-+      int err;
-+
-+      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+      priv->dev = dev;
-+
-+      priv->format = (uintptr_t)of_device_get_match_data(dev);
-+
-+      priv->mtd = of_get_mtd_device_by_node(np);
-+      if (IS_ERR(priv->mtd)) {
-+              dev_err_probe(dev, PTR_ERR(priv->mtd), "Failed to get %pOF MTD\n", np);
-+              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->mtd->size;
-+
-+      return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
-+}
-+
-+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, },
-+      {},
-+};
-+
-+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,
-+      },
-+};
-+module_platform_driver(u_boot_env_driver);
-+
-+MODULE_AUTHOR("Rafał Miłecki");
-+MODULE_LICENSE("GPL");
-+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.10/801-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch
deleted file mode 100644 (file)
index 3a6b76a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 15 Sep 2022 22:06:29 +0200
-Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-DT binding allows specifying NVMEM cells as NVMEM device (provider)
-subnodes. Looks for such subnodes when building NVMEM cells.
-
-This allows NVMEM consumers to use U-Boot environment variables.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u
-                       return -ENOMEM;
-               priv->cells[idx].offset = data_offset + value - data;
-               priv->cells[idx].bytes = strlen(value);
-+              priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
-       }
-       if (WARN_ON(idx != priv->ncells))
diff --git a/target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.10/801-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch
deleted file mode 100644 (file)
index 6b40557..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 18 Aug 2022 06:38:37 +0200
-Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32
-
-Reported-by: kernel test robot <lkp@intel.com>
-Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-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
-@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo
-               data_offset = offsetof(struct u_boot_env_image_redundant, data);
-               break;
-       }
--      crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
-+      crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-       crc32_data_len = priv->mtd->size - crc32_data_offset;
-       data_len = priv->mtd->size - data_offset;
diff --git a/target/linux/generic/backport-5.10/802-v5.12-0002-nvmem-imx-iim-Use-of_device_get_match_data.patch b/target/linux/generic/backport-5.10/802-v5.12-0002-nvmem-imx-iim-Use-of_device_get_match_data.patch
new file mode 100644 (file)
index 0000000..9a7ba7f
--- /dev/null
@@ -0,0 +1,41 @@
+From 579db09c6106977c0496f2cca48606b289df4bdf Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@gmail.com>
+Date: Fri, 29 Jan 2021 17:14:27 +0000
+Subject: [PATCH] nvmem: imx-iim: Use of_device_get_match_data()
+
+The retrieval of driver data via of_device_get_match_data() can make
+the code simpler.
+
+Use of_device_get_match_data() to simplify the code.
+
+Signed-off-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210129171430.11328-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-iim.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/nvmem/imx-iim.c
++++ b/drivers/nvmem/imx-iim.c
+@@ -96,7 +96,6 @@ MODULE_DEVICE_TABLE(of, imx_iim_dt_ids);
+ static int imx_iim_probe(struct platform_device *pdev)
+ {
+-      const struct of_device_id *of_id;
+       struct device *dev = &pdev->dev;
+       struct iim_priv *iim;
+       struct nvmem_device *nvmem;
+@@ -111,11 +110,7 @@ static int imx_iim_probe(struct platform
+       if (IS_ERR(iim->base))
+               return PTR_ERR(iim->base);
+-      of_id = of_match_device(imx_iim_dt_ids, dev);
+-      if (!of_id)
+-              return -ENODEV;
+-
+-      drvdata = of_id->data;
++      drvdata = of_device_get_match_data(&pdev->dev);
+       iim->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(iim->clk))
diff --git a/target/linux/generic/backport-5.10/802-v5.12-0003-nvmem-Add-driver-to-expose-reserved-memory-as-nvmem.patch b/target/linux/generic/backport-5.10/802-v5.12-0003-nvmem-Add-driver-to-expose-reserved-memory-as-nvmem.patch
new file mode 100644 (file)
index 0000000..f3ed563
--- /dev/null
@@ -0,0 +1,160 @@
+From 5a3fa75a4d9cb6bcfc9081ef224a4cdcd4b3eafe Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Fri, 29 Jan 2021 17:14:29 +0000
+Subject: [PATCH] nvmem: Add driver to expose reserved memory as nvmem
+
+Firmware/co-processors might use reserved memory areas in order to pass
+data stemming from an nvmem device otherwise non accessible to Linux.
+For example an EEPROM memory only physically accessible to firmware, or
+data only accessible early at boot time.
+
+In order to expose this data to other drivers and user-space, the driver
+models the reserved memory area as an nvmem device.
+
+Tested-by: Tim Gover <tim.gover@raspberrypi.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210129171430.11328-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig  |  8 ++++
+ drivers/nvmem/Makefile |  2 +
+ drivers/nvmem/rmem.c   | 97 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/of/platform.c  |  1 +
+ 4 files changed, 108 insertions(+)
+ create mode 100644 drivers/nvmem/rmem.c
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -270,4 +270,12 @@ config SPRD_EFUSE
+         This driver can also be built as a module. If so, the module
+         will be called nvmem-sprd-efuse.
++config NVMEM_RMEM
++      tristate "Reserved Memory Based Driver Support"
++      help
++        This drivers maps reserved memory into an nvmem device. It might be
++        useful to expose information left by firmware in memory.
++
++        This driver can also be built as a module. If so, the module
++        will be called nvmem-rmem.
+ endif
+--- a/drivers/nvmem/Makefile
++++ b/drivers/nvmem/Makefile
+@@ -55,3 +55,5 @@ obj-$(CONFIG_NVMEM_ZYNQMP)   += nvmem_zynq
+ nvmem_zynqmp_nvmem-y          := zynqmp_nvmem.o
+ obj-$(CONFIG_SPRD_EFUSE)      += nvmem_sprd_efuse.o
+ nvmem_sprd_efuse-y            := sprd-efuse.o
++obj-$(CONFIG_NVMEM_RMEM)      += nvmem-rmem.o
++nvmem-rmem-y                  := rmem.o
+--- /dev/null
++++ b/drivers/nvmem/rmem.c
+@@ -0,0 +1,97 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Copyright (C) 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
++ */
++
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of_reserved_mem.h>
++#include <linux/platform_device.h>
++
++struct rmem {
++      struct device *dev;
++      struct nvmem_device *nvmem;
++      struct reserved_mem *mem;
++
++      phys_addr_t size;
++};
++
++static int rmem_read(void *context, unsigned int offset,
++                   void *val, size_t bytes)
++{
++      struct rmem *priv = context;
++      size_t available = priv->mem->size;
++      loff_t off = offset;
++      void *addr;
++      int count;
++
++      /*
++       * Only map the reserved memory at this point to avoid potential rogue
++       * kernel threads inadvertently modifying it. Based on the current
++       * uses-cases for this driver, the performance hit isn't a concern.
++       * Nor is likely to be, given the nature of the subsystem. Most nvmem
++       * devices operate over slow buses to begin with.
++       *
++       * An alternative would be setting the memory as RO, set_memory_ro(),
++       * but as of Dec 2020 this isn't possible on arm64.
++       */
++      addr = memremap(priv->mem->base, available, MEMREMAP_WB);
++      if (IS_ERR(addr)) {
++              dev_err(priv->dev, "Failed to remap memory region\n");
++              return PTR_ERR(addr);
++      }
++
++      count = memory_read_from_buffer(val, bytes, &off, addr, available);
++
++      memunmap(addr);
++
++      return count;
++}
++
++static int rmem_probe(struct platform_device *pdev)
++{
++      struct nvmem_config config = { };
++      struct device *dev = &pdev->dev;
++      struct reserved_mem *mem;
++      struct rmem *priv;
++
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++      priv->dev = dev;
++
++      mem = of_reserved_mem_lookup(dev->of_node);
++      if (!mem) {
++              dev_err(dev, "Failed to lookup reserved memory\n");
++              return -EINVAL;
++      }
++      priv->mem = mem;
++
++      config.dev = dev;
++      config.priv = priv;
++      config.name = "rmem";
++      config.size = mem->size;
++      config.reg_read = rmem_read;
++
++      return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
++}
++
++static const struct of_device_id rmem_match[] = {
++      { .compatible = "nvmem-rmem", },
++      { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, rmem_match);
++
++static struct platform_driver rmem_driver = {
++      .probe = rmem_probe,
++      .driver = {
++              .name = "rmem",
++              .of_match_table = rmem_match,
++      },
++};
++module_platform_driver(rmem_driver);
++
++MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
++MODULE_DESCRIPTION("Reserved Memory Based nvmem Driver");
++MODULE_LICENSE("GPL");
+--- a/drivers/of/platform.c
++++ b/drivers/of/platform.c
+@@ -511,6 +511,7 @@ static const struct of_device_id reserve
+       { .compatible = "qcom,rmtfs-mem" },
+       { .compatible = "qcom,cmd-db" },
+       { .compatible = "ramoops" },
++      { .compatible = "nvmem-rmem" },
+       {}
+ };
diff --git a/target/linux/generic/backport-5.10/802-v5.12-0005-nvmem-Kconfig-Correct-typo-in-NVMEM_RMEM.patch b/target/linux/generic/backport-5.10/802-v5.12-0005-nvmem-Kconfig-Correct-typo-in-NVMEM_RMEM.patch
new file mode 100644 (file)
index 0000000..129d070
--- /dev/null
@@ -0,0 +1,28 @@
+From b31f1eb41c140d7979f855df73064b3a3ae8055a Mon Sep 17 00:00:00 2001
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Date: Fri, 5 Feb 2021 10:08:52 +0000
+Subject: [PATCH] nvmem: Kconfig: Correct typo in NVMEM_RMEM
+
+s/drivers/driver/ as the configuration selects a single driver.
+
+Suggested-by: Randy Dunlap <rdunlap@infradead.org>
+Acked-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210205100853.32372-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -273,7 +273,7 @@ config SPRD_EFUSE
+ config NVMEM_RMEM
+       tristate "Reserved Memory Based Driver Support"
+       help
+-        This drivers maps reserved memory into an nvmem device. It might be
++        This driver maps reserved memory into an nvmem device. It might be
+         useful to expose information left by firmware in memory.
+         This driver can also be built as a module. If so, the module
diff --git a/target/linux/generic/backport-5.10/802-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch b/target/linux/generic/backport-5.10/802-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch
deleted file mode 100644 (file)
index b7870ee..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From dbc2f62061c6bfba0aee93161ee3194dcee84bd0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 29 Apr 2022 17:26:46 +0100
-Subject: [PATCH] nvmem: core: support passing DT node in cell info
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Some hardware may have NVMEM cells described in Device Tree using
-individual nodes. Let drivers pass such nodes to the NVMEM subsystem so
-they can be later used by NVMEM consumers.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20220429162701.2222-2-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/nvmem/core.c           | 1 +
- include/linux/nvmem-consumer.h | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/drivers/nvmem/core.c
-+++ b/drivers/nvmem/core.c
-@@ -374,6 +374,7 @@ static int nvmem_cell_info_to_nvmem_cell
-       cell->bit_offset = info->bit_offset;
-       cell->nbits = info->nbits;
-+      cell->np = info->np;
-       if (cell->nbits)
-               cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
---- a/include/linux/nvmem-consumer.h
-+++ b/include/linux/nvmem-consumer.h
-@@ -25,6 +25,7 @@ struct nvmem_cell_info {
-       unsigned int            bytes;
-       unsigned int            bit_offset;
-       unsigned int            nbits;
-+      struct device_node      *np;
- };
- /**
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0001-nvmem-convert-comma-to-semicolon.patch b/target/linux/generic/backport-5.10/803-v5.13-0001-nvmem-convert-comma-to-semicolon.patch
new file mode 100644 (file)
index 0000000..b611ffe
--- /dev/null
@@ -0,0 +1,39 @@
+From e050f160d4832ce5227fb6ca934969cec0fc48be Mon Sep 17 00:00:00 2001
+From: Zheng Yongjun <zhengyongjun3@huawei.com>
+Date: Tue, 30 Mar 2021 12:12:33 +0100
+Subject: [PATCH] nvmem: convert comma to semicolon
+
+Replace a comma between expression statements by a semicolon.
+
+Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
+Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210330111241.19401-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qcom-spmi-sdam.c | 2 +-
+ drivers/nvmem/snvs_lpgpr.c     | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/nvmem/qcom-spmi-sdam.c
++++ b/drivers/nvmem/qcom-spmi-sdam.c
+@@ -141,7 +141,7 @@ static int sdam_probe(struct platform_de
+       sdam->sdam_config.dev = &pdev->dev;
+       sdam->sdam_config.name = "spmi_sdam";
+       sdam->sdam_config.id = NVMEM_DEVID_AUTO;
+-      sdam->sdam_config.owner = THIS_MODULE,
++      sdam->sdam_config.owner = THIS_MODULE;
+       sdam->sdam_config.stride = 1;
+       sdam->sdam_config.word_size = 1;
+       sdam->sdam_config.reg_read = sdam_read;
+--- a/drivers/nvmem/snvs_lpgpr.c
++++ b/drivers/nvmem/snvs_lpgpr.c
+@@ -123,7 +123,7 @@ static int snvs_lpgpr_probe(struct platf
+       cfg->dev = dev;
+       cfg->stride = 4;
+       cfg->word_size = 4;
+-      cfg->size = dcfg->size,
++      cfg->size = dcfg->size;
+       cfg->owner = THIS_MODULE;
+       cfg->reg_read  = snvs_lpgpr_read;
+       cfg->reg_write = snvs_lpgpr_write;
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0003-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch b/target/linux/generic/backport-5.10/803-v5.13-0003-nvmem-brcm_nvram-new-driver-exposing-Broadcom-s-NVRA.patch
new file mode 100644 (file)
index 0000000..17be01c
--- /dev/null
@@ -0,0 +1,126 @@
+From 3fef9ed0627af30753a2404b8bd59d92cdb4c0ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 30 Mar 2021 12:12:36 +0100
+Subject: [PATCH] nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This driver provides access to Broadcom's NVRAM.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210330111241.19401-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig      |  9 +++++
+ drivers/nvmem/Makefile     |  2 +
+ drivers/nvmem/brcm_nvram.c | 78 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 89 insertions(+)
+ create mode 100644 drivers/nvmem/brcm_nvram.c
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -278,4 +278,13 @@ config NVMEM_RMEM
+         This driver can also be built as a module. If so, the module
+         will be called nvmem-rmem.
++
++config NVMEM_BRCM_NVRAM
++      tristate "Broadcom's NVRAM support"
++      depends on ARCH_BCM_5301X || COMPILE_TEST
++      depends on HAS_IOMEM
++      help
++        This driver provides support for Broadcom's NVRAM that can be accessed
++        using I/O mapping.
++
+ endif
+--- a/drivers/nvmem/Makefile
++++ b/drivers/nvmem/Makefile
+@@ -57,3 +57,5 @@ obj-$(CONFIG_SPRD_EFUSE)     += nvmem_sprd_e
+ nvmem_sprd_efuse-y            := sprd-efuse.o
+ 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
+--- /dev/null
++++ b/drivers/nvmem/brcm_nvram.c
+@@ -0,0 +1,78 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
++ */
++
++#include <linux/io.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/nvmem-provider.h>
++#include <linux/platform_device.h>
++
++struct brcm_nvram {
++      struct device *dev;
++      void __iomem *base;
++};
++
++static int brcm_nvram_read(void *context, unsigned int offset, void *val,
++                         size_t bytes)
++{
++      struct brcm_nvram *priv = context;
++      u8 *dst = val;
++
++      while (bytes--)
++              *dst++ = readb(priv->base + offset++);
++
++      return 0;
++}
++
++static int brcm_nvram_probe(struct platform_device *pdev)
++{
++      struct nvmem_config config = {
++              .name = "brcm-nvram",
++              .reg_read = brcm_nvram_read,
++      };
++      struct device *dev = &pdev->dev;
++      struct resource *res;
++      struct brcm_nvram *priv;
++
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++      priv->dev = dev;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      priv->base = devm_ioremap_resource(dev, res);
++      if (IS_ERR(priv->base))
++              return PTR_ERR(priv->base);
++
++      config.dev = dev;
++      config.priv = priv;
++      config.size = resource_size(res);
++
++      return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
++}
++
++static const struct of_device_id brcm_nvram_of_match_table[] = {
++      { .compatible = "brcm,nvram", },
++      {},
++};
++
++static struct platform_driver brcm_nvram_driver = {
++      .probe = brcm_nvram_probe,
++      .driver = {
++              .name = "brcm_nvram",
++              .of_match_table = brcm_nvram_of_match_table,
++      },
++};
++
++static int __init brcm_nvram_init(void)
++{
++      return platform_driver_register(&brcm_nvram_driver);
++}
++
++subsys_initcall_sync(brcm_nvram_init);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0004-nvmem-core-Add-functions-to-make-number-reading-easy.patch b/target/linux/generic/backport-5.10/803-v5.13-0004-nvmem-core-Add-functions-to-make-number-reading-easy.patch
new file mode 100644 (file)
index 0000000..ff24567
--- /dev/null
@@ -0,0 +1,174 @@
+From a28e824fb8270eda43fd0f65c2a5fdf33f55c5eb Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Tue, 30 Mar 2021 12:12:37 +0100
+Subject: [PATCH] nvmem: core: Add functions to make number reading easy
+
+Sometimes the clients of nvmem just want to get a number out of
+nvmem. They don't want to think about exactly how many bytes the nvmem
+cell took up. They just want the number. Let's make it easy.
+
+In general this concept is useful because nvmem space is precious and
+usually the fewest bits are allocated that will hold a given value on
+a given system. However, even though small numbers might be fine on
+one system that doesn't mean that logically the number couldn't be
+bigger. Imagine nvmem containing a max frequency for a component. On
+one system perhaps that fits in 16 bits. On another system it might
+fit in 32 bits. The code reading this number doesn't care--it just
+wants the number.
+
+We'll provide two functions: nvmem_cell_read_variable_le_u32() and
+nvmem_cell_read_variable_le_u64().
+
+Comparing these to the existing functions like nvmem_cell_read_u32():
+* These new functions have no problems if the value was stored in
+  nvmem in fewer bytes. It's OK to use these function as long as the
+  value stored will fit in 32-bits (or 64-bits).
+* These functions avoid problems that the earlier APIs had with bit
+  offsets. For instance, you can't use nvmem_cell_read_u32() to read a
+  value has nbits=32 and bit_offset=4 because the nvmem cell must be
+  at least 5 bytes big to hold this value. The new API accounts for
+  this and works fine.
+* These functions make it very explicit that they assume that the
+  number was stored in little endian format. The old functions made
+  this assumption whenever bit_offset was non-zero (see
+  nvmem_shift_read_buffer_in_place()) but didn't whenever the
+  bit_offset was zero.
+
+NOTE: it's assumed that we don't need an 8-bit or 16-bit version of
+this function. The 32-bit version of the function can be used to read
+8-bit or 16-bit data.
+
+At the moment, I'm only adding the "unsigned" versions of these
+functions, but if it ends up being useful someone could add a "signed"
+version that did 2's complement sign extension.
+
+At the moment, I'm only adding the "little endian" versions of these
+functions. Adding the "big endian" version would require adding "big
+endian" support to nvmem_shift_read_buffer_in_place().
+
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210330111241.19401-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c           | 95 ++++++++++++++++++++++++++++++++++
+ include/linux/nvmem-consumer.h |  4 ++
+ 2 files changed, 99 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1612,6 +1612,101 @@ int nvmem_cell_read_u64(struct device *d
+ }
+ EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
++static void *nvmem_cell_read_variable_common(struct device *dev,
++                                           const char *cell_id,
++                                           size_t max_len, size_t *len)
++{
++      struct nvmem_cell *cell;
++      int nbits;
++      void *buf;
++
++      cell = nvmem_cell_get(dev, cell_id);
++      if (IS_ERR(cell))
++              return cell;
++
++      nbits = cell->nbits;
++      buf = nvmem_cell_read(cell, len);
++      nvmem_cell_put(cell);
++      if (IS_ERR(buf))
++              return buf;
++
++      /*
++       * If nbits is set then nvmem_cell_read() can significantly exaggerate
++       * the length of the real data. Throw away the extra junk.
++       */
++      if (nbits)
++              *len = DIV_ROUND_UP(nbits, 8);
++
++      if (*len > max_len) {
++              kfree(buf);
++              return ERR_PTR(-ERANGE);
++      }
++
++      return buf;
++}
++
++/**
++ * nvmem_cell_read_variable_le_u32() - Read up to 32-bits of data as a little endian number.
++ *
++ * @dev: Device that requests the nvmem cell.
++ * @cell_id: Name of nvmem cell to read.
++ * @val: pointer to output value.
++ *
++ * Return: 0 on success or negative errno.
++ */
++int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
++                                  u32 *val)
++{
++      size_t len;
++      u8 *buf;
++      int i;
++
++      buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      /* Copy w/ implicit endian conversion */
++      *val = 0;
++      for (i = 0; i < len; i++)
++              *val |= buf[i] << (8 * i);
++
++      kfree(buf);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u32);
++
++/**
++ * nvmem_cell_read_variable_le_u64() - Read up to 64-bits of data as a little endian number.
++ *
++ * @dev: Device that requests the nvmem cell.
++ * @cell_id: Name of nvmem cell to read.
++ * @val: pointer to output value.
++ *
++ * Return: 0 on success or negative errno.
++ */
++int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
++                                  u64 *val)
++{
++      size_t len;
++      u8 *buf;
++      int i;
++
++      buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
++      if (IS_ERR(buf))
++              return PTR_ERR(buf);
++
++      /* Copy w/ implicit endian conversion */
++      *val = 0;
++      for (i = 0; i < len; i++)
++              *val |= buf[i] << (8 * i);
++
++      kfree(buf);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(nvmem_cell_read_variable_le_u64);
++
+ /**
+  * nvmem_device_cell_read() - Read a given nvmem device and cell
+  *
+--- a/include/linux/nvmem-consumer.h
++++ b/include/linux/nvmem-consumer.h
+@@ -65,6 +65,10 @@ int nvmem_cell_read_u8(struct device *de
+ int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val);
+ int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val);
+ int nvmem_cell_read_u64(struct device *dev, const char *cell_id, u64 *val);
++int nvmem_cell_read_variable_le_u32(struct device *dev, const char *cell_id,
++                                  u32 *val);
++int nvmem_cell_read_variable_le_u64(struct device *dev, const char *cell_id,
++                                  u64 *val);
+ /* direct nvmem device read/write interface */
+ struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0005-nvmem-core-Fix-unintentional-sign-extension-issue.patch b/target/linux/generic/backport-5.10/803-v5.13-0005-nvmem-core-Fix-unintentional-sign-extension-issue.patch
new file mode 100644 (file)
index 0000000..72133d3
--- /dev/null
@@ -0,0 +1,34 @@
+From 55022fdeace8e432f008787ce03703bdcc9c3ca9 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 30 Mar 2021 12:12:38 +0100
+Subject: [PATCH] nvmem: core: Fix unintentional sign extension issue
+
+The shifting of the u8 integer buf[3] by 24 bits to the left will
+be promoted to a 32 bit signed int and then sign-extended to a
+u64. In the event that the top bit of buf[3] is set then all
+then all the upper 32 bits of the u64 end up as also being set
+because of the sign-extension. Fix this by casting buf[i] to
+a u64 before the shift.
+
+Fixes: a28e824fb827 ("nvmem: core: Add functions to make number reading easy")
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Addresses-Coverity: ("Unintended sign extension")
+Link: https://lore.kernel.org/r/20210330111241.19401-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1699,7 +1699,7 @@ int nvmem_cell_read_variable_le_u64(stru
+       /* Copy w/ implicit endian conversion */
+       *val = 0;
+       for (i = 0; i < len; i++)
+-              *val |= buf[i] << (8 * i);
++              *val |= (uint64_t)buf[i] << (8 * i);
+       kfree(buf);
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0006-nvmem-rmem-fix-undefined-reference-to-memremap.patch b/target/linux/generic/backport-5.10/803-v5.13-0006-nvmem-rmem-fix-undefined-reference-to-memremap.patch
new file mode 100644 (file)
index 0000000..9e13fb6
--- /dev/null
@@ -0,0 +1,29 @@
+From cc1bc56fdc76a55bb8fae9a145a2e60bf22fb129 Mon Sep 17 00:00:00 2001
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Date: Tue, 30 Mar 2021 12:12:39 +0100
+Subject: [PATCH] nvmem: rmem: fix undefined reference to memremap
+
+Fix below error reporte by kernel test robot
+rmem.c:(.text+0x14e): undefined reference to memremap
+s390x-linux-gnu-ld: rmem.c:(.text+0x1b6): undefined reference to memunmap
+
+Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem")
+Reported-by: kernel test robot <lkp@intel.com>
+Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210330111241.19401-9-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -272,6 +272,7 @@ config SPRD_EFUSE
+ config NVMEM_RMEM
+       tristate "Reserved Memory Based Driver Support"
++      depends on HAS_IOMEM
+       help
+         This driver maps reserved memory into an nvmem device. It might be
+         useful to expose information left by firmware in memory.
diff --git a/target/linux/generic/backport-5.10/803-v5.13-0007-nvmem-qfprom-Add-support-for-fuse-blowing-on-sc7280.patch b/target/linux/generic/backport-5.10/803-v5.13-0007-nvmem-qfprom-Add-support-for-fuse-blowing-on-sc7280.patch
new file mode 100644 (file)
index 0000000..0e75d4c
--- /dev/null
@@ -0,0 +1,102 @@
+From 5a1bea2a2572ce5eb4bdcf432a6929681ee381f2 Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@codeaurora.org>
+Date: Tue, 30 Mar 2021 12:12:41 +0100
+Subject: [PATCH] nvmem: qfprom: Add support for fuse blowing on sc7280
+
+Handle the differences across LDO voltage needed for blowing fuses,
+and the blow timer value, identified using a minor version of 15
+on sc7280.
+
+Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
+Signed-off-by: Ravi Kumar Bokka <rbokka@codeaurora.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210330111241.19401-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qfprom.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -45,11 +45,13 @@ MODULE_PARM_DESC(read_raw_data, "Read ra
+  * @qfprom_blow_timer_value: The timer value of qfprom when doing efuse blow.
+  * @qfprom_blow_set_freq:    The frequency required to set when we start the
+  *                           fuse blowing.
++ * @qfprom_blow_uV:          LDO voltage to be set when doing efuse blow
+  */
+ struct qfprom_soc_data {
+       u32 accel_value;
+       u32 qfprom_blow_timer_value;
+       u32 qfprom_blow_set_freq;
++      int qfprom_blow_uV;
+ };
+ /**
+@@ -111,6 +113,15 @@ static const struct qfprom_soc_compatibl
+       .nkeepout = ARRAY_SIZE(sc7180_qfprom_keepout)
+ };
++static const struct nvmem_keepout sc7280_qfprom_keepout[] = {
++      {.start = 0x128, .end = 0x148},
++      {.start = 0x238, .end = 0x248}
++};
++
++static const struct qfprom_soc_compatible_data sc7280_qfprom = {
++      .keepout = sc7280_qfprom_keepout,
++      .nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
++};
+ /**
+  * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
+  * @priv: Our driver data.
+@@ -168,6 +179,7 @@ static int qfprom_enable_fuse_blowing(co
+                                     struct qfprom_touched_values *old)
+ {
+       int ret;
++      int qfprom_blow_uV = priv->soc_data->qfprom_blow_uV;
+       ret = clk_prepare_enable(priv->secclk);
+       if (ret) {
+@@ -187,9 +199,9 @@ static int qfprom_enable_fuse_blowing(co
+        * a rail shared do don't specify a max--regulator constraints
+        * will handle.
+        */
+-      ret = regulator_set_voltage(priv->vcc, 1800000, INT_MAX);
++      ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
+       if (ret) {
+-              dev_err(priv->dev, "Failed to set 1.8 voltage\n");
++              dev_err(priv->dev, "Failed to set %duV\n", qfprom_blow_uV);
+               goto err_clk_rate_set;
+       }
+@@ -311,6 +323,14 @@ static const struct qfprom_soc_data qfpr
+       .accel_value = 0xD10,
+       .qfprom_blow_timer_value = 25,
+       .qfprom_blow_set_freq = 4800000,
++      .qfprom_blow_uV = 1800000,
++};
++
++static const struct qfprom_soc_data qfprom_7_15_data = {
++      .accel_value = 0xD08,
++      .qfprom_blow_timer_value = 24,
++      .qfprom_blow_set_freq = 4800000,
++      .qfprom_blow_uV = 1900000,
+ };
+ static int qfprom_probe(struct platform_device *pdev)
+@@ -379,6 +399,8 @@ static int qfprom_probe(struct platform_
+               if (major_version == 7 && minor_version == 8)
+                       priv->soc_data = &qfprom_7_8_data;
++              if (major_version == 7 && minor_version == 15)
++                      priv->soc_data = &qfprom_7_15_data;
+               priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
+               if (IS_ERR(priv->vcc))
+@@ -405,6 +427,7 @@ static int qfprom_probe(struct platform_
+ static const struct of_device_id qfprom_of_match[] = {
+       { .compatible = "qcom,qfprom",},
+       { .compatible = "qcom,sc7180-qfprom", .data = &sc7180_qfprom},
++      { .compatible = "qcom,sc7280-qfprom", .data = &sc7280_qfprom},
+       {/* sentinel */},
+ };
+ MODULE_DEVICE_TABLE(of, qfprom_of_match);
diff --git a/target/linux/generic/backport-5.10/803-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch b/target/linux/generic/backport-5.10/803-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch
deleted file mode 100644 (file)
index 69d5a1b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From 7a69ff9c9bde03a690ea783970f664782fc303d8 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Fri, 4 Nov 2022 17:52:03 +0100
-Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant
- u-boot-env
-
-The Western Digital MyBook Live (PowerPC 464/APM82181)
-has a set of redundant u-boot-env. Loading up the driver
-the following error:
-
-| u_boot_env: Invalid calculated CRC32: 0x4f8f2c86 (expected: 0x98b14514)
-| u_boot_env: probe of partition@1e000 failed with error -22
-
-Looking up the userspace libubootenv utilities source [0],
-it looks like the "mark" or "flag" is not part of the
-crc32 sum... which is unfortunate :(
-
-|static int libuboot_load(struct uboot_ctx *ctx)
-|{
-|[...]
-|       if (ctx->redundant) {
-|              [...]
-|               offsetdata = offsetof(struct uboot_env_redund, data);
-|              [...]                                   //-----^^
-|       }
-|       usable_envsize = ctx->size - offsetdata;
-|       buf[0] = malloc(bufsize);
-|[...]
-|      for (i = 0; i < copies; i++) {
-|              data = (uint8_t *)(buf[i] + offsetdata);
-|               uint32_t crc;
-|
-|              ret = devread(ctx, i, buf[i]);
-|              [...]
-|              crc = *(uint32_t *)(buf[i] + offsetcrc);
-|               dev->crc = crc32(0, (uint8_t *)data, usable_envsize);
-|
-
-[0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951
-Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
----
- 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
-@@ -135,7 +135,7 @@ static int u_boot_env_parse(struct u_boo
-               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, mark);
-+              crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
-               data_offset = offsetof(struct u_boot_env_image_redundant, data);
-               break;
-       }
diff --git a/target/linux/generic/backport-5.10/803-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/backport-5.10/803-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
deleted file mode 100644 (file)
index 7d6723b..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-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
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch fixes crc32 error on Big-Endianness system by conversion of
-calculated crc32 value.
-
-Little-Endianness system:
-
-  obtained crc32: Little
-calculated crc32: Little
-
-Big-Endianness system:
-
-  obtained crc32: Little
-calculated crc32: Big
-
-log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness):
-
-[    8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88)
-[    8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22
-
-Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
-
-Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
-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
-@@ -143,7 +143,7 @@ static int u_boot_env_parse(struct u_boo
-       crc32_data_len = priv->mtd->size - crc32_data_offset;
-       data_len = priv->mtd->size - data_offset;
--      calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
-+      calc = le32_to_cpu((__le32)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;
diff --git a/target/linux/generic/backport-5.10/803-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-5.10/803-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch
deleted file mode 100644 (file)
index 429b24f..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From 5b4eaafbeac472fc19049152f18e88aecb2b2829 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 17 Oct 2022 09:17:22 +0200
-Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They
-decided to store U-Boot environment data inside U-Boot partition and to
-use a custom header (with "uEnv" magic and env data length).
-
-Add support for Broadcom's specific binding and their custom format.
-
-Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
----
- drivers/nvmem/u-boot-env.c | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -16,6 +16,7 @@
- enum u_boot_env_format {
-       U_BOOT_FORMAT_SINGLE,
-       U_BOOT_FORMAT_REDUNDANT,
-+      U_BOOT_FORMAT_BROADCOM,
- };
- struct u_boot_env {
-@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant {
-       uint8_t data[];
- } __packed;
-+struct u_boot_env_image_broadcom {
-+      __le32 magic;
-+      __le32 len;
-+      __le32 crc32;
-+      uint8_t data[0];
-+} __packed;
-+
- static int u_boot_env_read(void *context, unsigned int offset, void *val,
-                          size_t bytes)
- {
-@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo
-               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;
-       }
-       crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
-       crc32_data_len = priv->mtd->size - crc32_data_offset;
-@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_
-       { .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, },
-       {},
- };
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0001-nvmem-core-allow-specifying-of_node.patch b/target/linux/generic/backport-5.10/804-v5.14-0001-nvmem-core-allow-specifying-of_node.patch
new file mode 100644 (file)
index 0000000..8c5a55e
--- /dev/null
@@ -0,0 +1,80 @@
+From 1333a6779501f4cc662ff5c8b36b0a22f3a7ddc6 Mon Sep 17 00:00:00 2001
+From: Michael Walle <michael@walle.cc>
+Date: Sat, 24 Apr 2021 13:06:04 +0200
+Subject: [PATCH] nvmem: core: allow specifying of_node
+
+Until now, the of_node of the parent device is used. Some devices
+provide more than just the nvmem provider. To avoid name space clashes,
+add a way to allow specifying the nvmem cells in subnodes. Consider the
+following example:
+
+    flash@0 {
+        compatible = "jedec,spi-nor";
+
+        partitions {
+            compatible = "fixed-partitions";
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            partition@0 {
+                reg = <0x000000 0x010000>;
+            };
+        };
+
+        otp {
+            compatible = "user-otp";
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            serial-number@0 {
+                reg = <0x0 0x8>;
+            };
+        };
+    };
+
+There the nvmem provider might be the MTD partition or the OTP region of
+the flash.
+
+Add a new config->of_node parameter, which if set, will be used instead
+of the parent's of_node.
+
+Signed-off-by: Michael Walle <michael@walle.cc>
+Acked-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20210424110608.15748-2-michael@walle.cc
+---
+ drivers/nvmem/core.c           | 4 +++-
+ include/linux/nvmem-provider.h | 2 ++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -794,7 +794,9 @@ struct nvmem_device *nvmem_register(cons
+       nvmem->reg_write = config->reg_write;
+       nvmem->keepout = config->keepout;
+       nvmem->nkeepout = config->nkeepout;
+-      if (!config->no_of_node)
++      if (config->of_node)
++              nvmem->dev.of_node = config->of_node;
++      else if (!config->no_of_node)
+               nvmem->dev.of_node = config->dev->of_node;
+       switch (config->id) {
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -57,6 +57,7 @@ struct nvmem_keepout {
+  * @type:     Type of the nvmem storage
+  * @read_only:        Device is read-only.
+  * @root_only:        Device is accessibly to root only.
++ * @of_node:  If given, this will be used instead of the parent's of_node.
+  * @no_of_node:       Device should not use the parent's of_node even if it's !NULL.
+  * @reg_read: Callback to read data.
+  * @reg_write:        Callback to write data.
+@@ -86,6 +87,7 @@ struct nvmem_config {
+       enum nvmem_type         type;
+       bool                    read_only;
+       bool                    root_only;
++      struct device_node      *of_node;
+       bool                    no_of_node;
+       nvmem_reg_read_t        reg_read;
+       nvmem_reg_write_t       reg_write;
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0002-nvmem-sprd-Fix-an-error-message.patch b/target/linux/generic/backport-5.10/804-v5.14-0002-nvmem-sprd-Fix-an-error-message.patch
new file mode 100644 (file)
index 0000000..db88328
--- /dev/null
@@ -0,0 +1,30 @@
+From 20be064ec864086bca7a4eb62c772a397b44afb7 Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Fri, 7 May 2021 19:02:48 +0200
+Subject: [PATCH] nvmem: sprd: Fix an error message
+
+'ret' is known to be 0 here.
+The expected error status is stored in 'status', so use it instead.
+
+Also change %d in %u, because status is an u32, not a int.
+
+Fixes: 096030e7f449 ("nvmem: sprd: Add Spreadtrum SoCs eFuse support")
+Acked-by: Chunyan Zhang <zhang.lyra@gmail.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://lore.kernel.org/r/5bc44aace2fe7e1c91d8b35c8fe31e7134ceab2c.1620406852.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sprd-efuse.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -234,7 +234,7 @@ static int sprd_efuse_raw_prog(struct sp
+       status = readl(efuse->base + SPRD_EFUSE_ERR_FLAG);
+       if (status) {
+               dev_err(efuse->dev,
+-                      "write error status %d of block %d\n", ret, blk);
++                      "write error status %u of block %d\n", status, blk);
+               writel(SPRD_EFUSE_ERR_CLR_MASK,
+                      efuse->base + SPRD_EFUSE_ERR_CLR);
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0003-nvmem-sunxi_sid-Set-type-to-OTP.patch b/target/linux/generic/backport-5.10/804-v5.14-0003-nvmem-sunxi_sid-Set-type-to-OTP.patch
new file mode 100644 (file)
index 0000000..37694e5
--- /dev/null
@@ -0,0 +1,27 @@
+From 78a005a22d5608b266eafa011b093a33284c52ce Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Fri, 11 Jun 2021 09:33:45 +0100
+Subject: [PATCH] nvmem: sunxi_sid: Set type to OTP
+
+This device currently reports an "Unknown" type in sysfs.
+Since it is an eFuse hardware device, set its type to OTP.
+
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Acked-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210611083348.20170-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sunxi_sid.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sunxi_sid.c
++++ b/drivers/nvmem/sunxi_sid.c
+@@ -142,6 +142,7 @@ static int sunxi_sid_probe(struct platfo
+       nvmem_cfg->dev = dev;
+       nvmem_cfg->name = "sunxi-sid";
++      nvmem_cfg->type = NVMEM_TYPE_OTP;
+       nvmem_cfg->read_only = true;
+       nvmem_cfg->size = cfg->size;
+       nvmem_cfg->word_size = 1;
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0004-nvmem-qfprom-minor-nit-fixes.patch b/target/linux/generic/backport-5.10/804-v5.14-0004-nvmem-qfprom-minor-nit-fixes.patch
new file mode 100644 (file)
index 0000000..bcab3e4
--- /dev/null
@@ -0,0 +1,46 @@
+From c813bb37bd32cb967060a2c573fae4ea518d32eb Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@codeaurora.org>
+Date: Fri, 11 Jun 2021 09:33:46 +0100
+Subject: [PATCH] nvmem: qfprom: minor nit fixes
+
+Fix a missed newline, change an 'if' to 'else if' and update
+a comment which is stale after the merge of '5a1bea2a: nvmem:
+qfprom: Add support for fuseblowing on sc7280'
+
+Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210611083348.20170-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qfprom.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -122,6 +122,7 @@ static const struct qfprom_soc_compatibl
+       .keepout = sc7280_qfprom_keepout,
+       .nkeepout = ARRAY_SIZE(sc7280_qfprom_keepout)
+ };
++
+ /**
+  * qfprom_disable_fuse_blowing() - Undo enabling of fuse blowing.
+  * @priv: Our driver data.
+@@ -195,7 +196,7 @@ static int qfprom_enable_fuse_blowing(co
+       }
+       /*
+-       * Hardware requires 1.8V min for fuse blowing; this may be
++       * Hardware requires a min voltage for fuse blowing; this may be
+        * a rail shared do don't specify a max--regulator constraints
+        * will handle.
+        */
+@@ -399,7 +400,7 @@ static int qfprom_probe(struct platform_
+               if (major_version == 7 && minor_version == 8)
+                       priv->soc_data = &qfprom_7_8_data;
+-              if (major_version == 7 && minor_version == 15)
++              else if (major_version == 7 && minor_version == 15)
+                       priv->soc_data = &qfprom_7_15_data;
+               priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0005-nvmem-core-constify-nvmem_cell_read_variable_common-.patch b/target/linux/generic/backport-5.10/804-v5.14-0005-nvmem-core-constify-nvmem_cell_read_variable_common-.patch
new file mode 100644 (file)
index 0000000..55c3c5d
--- /dev/null
@@ -0,0 +1,52 @@
+From 1f7b4d87874624f4beb25253900a25306a193b8b Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Fri, 11 Jun 2021 09:33:47 +0100
+Subject: [PATCH] nvmem: core: constify nvmem_cell_read_variable_common()
+ return value
+
+The caller doesn't modify the memory pointed to by the pointer so it
+can be const.
+
+Suggested-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210611083348.20170-9-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1614,9 +1614,9 @@ int nvmem_cell_read_u64(struct device *d
+ }
+ EXPORT_SYMBOL_GPL(nvmem_cell_read_u64);
+-static void *nvmem_cell_read_variable_common(struct device *dev,
+-                                           const char *cell_id,
+-                                           size_t max_len, size_t *len)
++static const void *nvmem_cell_read_variable_common(struct device *dev,
++                                                 const char *cell_id,
++                                                 size_t max_len, size_t *len)
+ {
+       struct nvmem_cell *cell;
+       int nbits;
+@@ -1660,7 +1660,7 @@ int nvmem_cell_read_variable_le_u32(stru
+                                   u32 *val)
+ {
+       size_t len;
+-      u8 *buf;
++      const u8 *buf;
+       int i;
+       buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
+@@ -1691,7 +1691,7 @@ int nvmem_cell_read_variable_le_u64(stru
+                                   u64 *val)
+ {
+       size_t len;
+-      u8 *buf;
++      const u8 *buf;
+       int i;
+       buf = nvmem_cell_read_variable_common(dev, cell_id, sizeof(*val), &len);
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0006-nvmem-qfprom-Improve-the-comment-about-regulator-set.patch b/target/linux/generic/backport-5.10/804-v5.14-0006-nvmem-qfprom-Improve-the-comment-about-regulator-set.patch
new file mode 100644 (file)
index 0000000..d7ef8e6
--- /dev/null
@@ -0,0 +1,33 @@
+From 989f77e3fdee2e8f414dd1da9b6397d8763d414e Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Fri, 11 Jun 2021 09:33:48 +0100
+Subject: [PATCH] nvmem: qfprom: Improve the comment about regulator setting
+
+In review feedback Joe Perches found the existing comment
+confusing. Let's use something based on the wording proposed by Joe.
+
+Suggested-by: Joe Perches <joe@perches.com>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210611083348.20170-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qfprom.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -196,9 +196,9 @@ static int qfprom_enable_fuse_blowing(co
+       }
+       /*
+-       * Hardware requires a min voltage for fuse blowing; this may be
+-       * a rail shared do don't specify a max--regulator constraints
+-       * will handle.
++       * Hardware requires a minimum voltage for fuse blowing.
++       * This may be a shared rail so don't specify a maximum.
++       * Regulator constraints will cap to the actual maximum.
+        */
+       ret = regulator_set_voltage(priv->vcc, qfprom_blow_uV, INT_MAX);
+       if (ret) {
diff --git a/target/linux/generic/backport-5.10/804-v5.14-0007-nvmem-add-NVMEM_TYPE_FRAM.patch b/target/linux/generic/backport-5.10/804-v5.14-0007-nvmem-add-NVMEM_TYPE_FRAM.patch
new file mode 100644 (file)
index 0000000..06c541b
--- /dev/null
@@ -0,0 +1,36 @@
+From: Rafał Miłecki <rafal@milecki.pl>
+Subject: [PATCH] nvmem: add NVMEM_TYPE_FRAM
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -180,6 +180,7 @@ static const char * const nvmem_type_str
+       [NVMEM_TYPE_EEPROM] = "EEPROM",
+       [NVMEM_TYPE_OTP] = "OTP",
+       [NVMEM_TYPE_BATTERY_BACKED] = "Battery backed",
++      [NVMEM_TYPE_FRAM] = "FRAM",
+ };
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+@@ -361,6 +362,9 @@ static int nvmem_sysfs_setup_compat(stru
+       if (!config->base_dev)
+               return -EINVAL;
++      if (config->type == NVMEM_TYPE_FRAM)
++              bin_attr_nvmem_eeprom_compat.attr.name = "fram";
++
+       nvmem->eeprom = bin_attr_nvmem_eeprom_compat;
+       nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem);
+       nvmem->eeprom.size = nvmem->size;
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -25,6 +25,7 @@ enum nvmem_type {
+       NVMEM_TYPE_EEPROM,
+       NVMEM_TYPE_OTP,
+       NVMEM_TYPE_BATTERY_BACKED,
++      NVMEM_TYPE_FRAM,
+ };
+ #define NVMEM_DEVID_NONE      (-1)
diff --git a/target/linux/generic/backport-5.10/805-v5.15-0002-nvmem-qfprom-sc7280-Handle-the-additional-power-doma.patch b/target/linux/generic/backport-5.10/805-v5.15-0002-nvmem-qfprom-sc7280-Handle-the-additional-power-doma.patch
new file mode 100644 (file)
index 0000000..b71edd0
--- /dev/null
@@ -0,0 +1,89 @@
+From 7b808449f572d07bee840cd9da7e2fe6a1b8f4b5 Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@codeaurora.org>
+Date: Fri, 6 Aug 2021 09:59:46 +0100
+Subject: [PATCH] nvmem: qfprom: sc7280: Handle the additional power-domains
+ vote
+
+On sc7280, to reliably blow fuses, we need an additional vote
+on max performance state of 'MX' power-domain.
+Add support for power-domain performance state voting in the
+driver.
+
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210806085947.22682-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/qfprom.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/nvmem/qfprom.c
++++ b/drivers/nvmem/qfprom.c
+@@ -12,6 +12,8 @@
+ #include <linux/mod_devicetable.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/platform_device.h>
++#include <linux/pm_domain.h>
++#include <linux/pm_runtime.h>
+ #include <linux/property.h>
+ #include <linux/regulator/consumer.h>
+@@ -142,6 +144,9 @@ static void qfprom_disable_fuse_blowing(
+       writel(old->timer_val, priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
+       writel(old->accel_val, priv->qfpconf + QFPROM_ACCEL_OFFSET);
++      dev_pm_genpd_set_performance_state(priv->dev, 0);
++      pm_runtime_put(priv->dev);
++
+       /*
+        * This may be a shared rail and may be able to run at a lower rate
+        * when we're not blowing fuses.  At the moment, the regulator framework
+@@ -212,6 +217,14 @@ static int qfprom_enable_fuse_blowing(co
+               goto err_clk_rate_set;
+       }
++      ret = pm_runtime_get_sync(priv->dev);
++      if (ret < 0) {
++              pm_runtime_put_noidle(priv->dev);
++              dev_err(priv->dev, "Failed to enable power-domain\n");
++              goto err_reg_enable;
++      }
++      dev_pm_genpd_set_performance_state(priv->dev, INT_MAX);
++
+       old->timer_val = readl(priv->qfpconf + QFPROM_BLOW_TIMER_OFFSET);
+       old->accel_val = readl(priv->qfpconf + QFPROM_ACCEL_OFFSET);
+       writel(priv->soc_data->qfprom_blow_timer_value,
+@@ -221,6 +234,8 @@ static int qfprom_enable_fuse_blowing(co
+       return 0;
++err_reg_enable:
++      regulator_disable(priv->vcc);
+ err_clk_rate_set:
+       clk_set_rate(priv->secclk, old->clk_rate);
+ err_clk_prepared:
+@@ -320,6 +335,11 @@ static int qfprom_reg_read(void *context
+       return 0;
+ }
++static void qfprom_runtime_disable(void *data)
++{
++      pm_runtime_disable(data);
++}
++
+ static const struct qfprom_soc_data qfprom_7_8_data = {
+       .accel_value = 0xD10,
+       .qfprom_blow_timer_value = 25,
+@@ -420,6 +440,11 @@ static int qfprom_probe(struct platform_
+                       econfig.reg_write = qfprom_reg_write;
+       }
++      pm_runtime_enable(dev);
++      ret = devm_add_action_or_reset(dev, qfprom_runtime_disable, dev);
++      if (ret)
++              return ret;
++
+       nvmem = devm_nvmem_register(dev, &econfig);
+       return PTR_ERR_OR_ZERO(nvmem);
diff --git a/target/linux/generic/backport-5.10/805-v5.15-0003-nvmem-core-fix-error-handling-while-validating-keepo.patch b/target/linux/generic/backport-5.10/805-v5.15-0003-nvmem-core-fix-error-handling-while-validating-keepo.patch
new file mode 100644 (file)
index 0000000..59c9281
--- /dev/null
@@ -0,0 +1,36 @@
+From de0534df93474f268486c486ea7e01b44a478026 Mon Sep 17 00:00:00 2001
+From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Date: Fri, 6 Aug 2021 09:59:47 +0100
+Subject: [PATCH] nvmem: core: fix error handling while validating keepout
+ regions
+
+Current error path on failure of validating keepout regions is calling
+put_device, eventhough the device is not even registered at that point.
+
+Fix this by adding proper error handling of freeing ida and nvmem.
+
+Fixes: fd3bb8f54a88 ("nvmem: core: Add support for keepout regions")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210806085947.22682-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -826,8 +826,11 @@ struct nvmem_device *nvmem_register(cons
+       if (nvmem->nkeepout) {
+               rval = nvmem_validate_keepouts(nvmem);
+-              if (rval)
+-                      goto err_put_device;
++              if (rval) {
++                      ida_free(&nvmem_ida, nvmem->id);
++                      kfree(nvmem);
++                      return ERR_PTR(rval);
++              }
+       }
+       dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
diff --git a/target/linux/generic/backport-5.10/805-v5.15-0004-nvmem-nintendo-otp-Add-new-driver-for-the-Wii-and-Wi.patch b/target/linux/generic/backport-5.10/805-v5.15-0004-nvmem-nintendo-otp-Add-new-driver-for-the-Wii-and-Wi.patch
new file mode 100644 (file)
index 0000000..62d9e2a
--- /dev/null
@@ -0,0 +1,191 @@
+From 3683b761fe3a10ad18515acd5368dd601268cfe5 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Tue, 10 Aug 2021 16:30:36 +0100
+Subject: [PATCH] nvmem: nintendo-otp: Add new driver for the Wii and Wii U OTP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This OTP is read-only and contains various keys used by the console to
+decrypt, encrypt or verify various pieces of storage.
+
+Its size depends on the console, it is 128 bytes on the Wii and
+1024 bytes on the Wii U (split into eight 128 bytes banks).
+
+It can be used directly by writing into one register and reading from
+the other one, without any additional synchronisation.
+
+This driver was written based on reversed documentation, see:
+https://wiiubrew.org/wiki/Hardware/OTP
+
+Tested-by: Jonathan Neuschäfer <j.ne@posteo.net>  # on Wii
+Tested-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>  # on Wii U
+Signed-off-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20210810153036.1494-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig        |  11 ++++
+ drivers/nvmem/Makefile       |   2 +
+ drivers/nvmem/nintendo-otp.c | 124 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 137 insertions(+)
+ create mode 100644 drivers/nvmem/nintendo-otp.c
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -107,6 +107,17 @@ config MTK_EFUSE
+         This driver can also be built as a module. If so, the module
+         will be called efuse-mtk.
++config NVMEM_NINTENDO_OTP
++      tristate "Nintendo Wii and Wii U OTP Support"
++      help
++        This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
++
++        This memory contains common and per-console keys, signatures and
++        related data required to access peripherals.
++
++        This driver can also be built as a module. If so, the module
++        will be called nvmem-nintendo-otp.
++
+ config QCOM_QFPROM
+       tristate "QCOM QFPROM Support"
+       depends on ARCH_QCOM || COMPILE_TEST
+--- a/drivers/nvmem/Makefile
++++ b/drivers/nvmem/Makefile
+@@ -23,6 +23,8 @@ obj-$(CONFIG_NVMEM_LPC18XX_OTP)      += nvmem
+ nvmem_lpc18xx_otp-y           := lpc18xx_otp.o
+ obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o
+ nvmem-mxs-ocotp-y             := mxs-ocotp.o
++obj-$(CONFIG_NVMEM_NINTENDO_OTP)      += nvmem-nintendo-otp.o
++nvmem-nintendo-otp-y          := nintendo-otp.o
+ obj-$(CONFIG_MTK_EFUSE)               += nvmem_mtk-efuse.o
+ nvmem_mtk-efuse-y             := mtk-efuse.o
+ obj-$(CONFIG_QCOM_QFPROM)     += nvmem_qfprom.o
+--- /dev/null
++++ b/drivers/nvmem/nintendo-otp.c
+@@ -0,0 +1,124 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Nintendo Wii and Wii U OTP driver
++ *
++ * This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
++ *
++ * This memory contains common and per-console keys, signatures and
++ * related data required to access peripherals.
++ *
++ * Based on reversed documentation from https://wiiubrew.org/wiki/Hardware/OTP
++ *
++ * Copyright (C) 2021 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
++ */
++
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mod_devicetable.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++
++#define HW_OTPCMD  0
++#define HW_OTPDATA 4
++#define OTP_READ   0x80000000
++#define BANK_SIZE  128
++#define WORD_SIZE  4
++
++struct nintendo_otp_priv {
++      void __iomem *regs;
++};
++
++struct nintendo_otp_devtype_data {
++      const char *name;
++      unsigned int num_banks;
++};
++
++static const struct nintendo_otp_devtype_data hollywood_otp_data = {
++      .name = "wii-otp",
++      .num_banks = 1,
++};
++
++static const struct nintendo_otp_devtype_data latte_otp_data = {
++      .name = "wiiu-otp",
++      .num_banks = 8,
++};
++
++static int nintendo_otp_reg_read(void *context,
++                               unsigned int reg, void *_val, size_t bytes)
++{
++      struct nintendo_otp_priv *priv = context;
++      u32 *val = _val;
++      int words = bytes / WORD_SIZE;
++      u32 bank, addr;
++
++      while (words--) {
++              bank = (reg / BANK_SIZE) << 8;
++              addr = (reg / WORD_SIZE) % (BANK_SIZE / WORD_SIZE);
++              iowrite32be(OTP_READ | bank | addr, priv->regs + HW_OTPCMD);
++              *val++ = ioread32be(priv->regs + HW_OTPDATA);
++              reg += WORD_SIZE;
++      }
++
++      return 0;
++}
++
++static const struct of_device_id nintendo_otp_of_table[] = {
++      { .compatible = "nintendo,hollywood-otp", .data = &hollywood_otp_data },
++      { .compatible = "nintendo,latte-otp", .data = &latte_otp_data },
++      {/* sentinel */},
++};
++MODULE_DEVICE_TABLE(of, nintendo_otp_of_table);
++
++static int nintendo_otp_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      const struct of_device_id *of_id =
++              of_match_device(nintendo_otp_of_table, dev);
++      struct resource *res;
++      struct nvmem_device *nvmem;
++      struct nintendo_otp_priv *priv;
++
++      struct nvmem_config config = {
++              .stride = WORD_SIZE,
++              .word_size = WORD_SIZE,
++              .reg_read = nintendo_otp_reg_read,
++              .read_only = true,
++              .root_only = true,
++      };
++
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      priv->regs = devm_ioremap_resource(dev, res);
++      if (IS_ERR(priv->regs))
++              return PTR_ERR(priv->regs);
++
++      if (of_id->data) {
++              const struct nintendo_otp_devtype_data *data = of_id->data;
++              config.name = data->name;
++              config.size = data->num_banks * BANK_SIZE;
++      }
++
++      config.dev = dev;
++      config.priv = priv;
++
++      nvmem = devm_nvmem_register(dev, &config);
++
++      return PTR_ERR_OR_ZERO(nvmem);
++}
++
++static struct platform_driver nintendo_otp_driver = {
++      .probe = nintendo_otp_probe,
++      .driver = {
++              .name = "nintendo-otp",
++              .of_match_table = nintendo_otp_of_table,
++      },
++};
++module_platform_driver(nintendo_otp_driver);
++MODULE_AUTHOR("Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>");
++MODULE_DESCRIPTION("Nintendo Wii and Wii U OTP driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/generic/backport-5.10/805-v5.15-0005-nvmem-NVMEM_NINTENDO_OTP-should-depend-on-WII.patch b/target/linux/generic/backport-5.10/805-v5.15-0005-nvmem-NVMEM_NINTENDO_OTP-should-depend-on-WII.patch
new file mode 100644 (file)
index 0000000..02f8b6c
--- /dev/null
@@ -0,0 +1,29 @@
+From 7af526c740bdbd5b4dcebba04ace5b3b0c07801f Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Tue, 14 Sep 2021 11:29:49 +0200
+Subject: [PATCH] nvmem: NVMEM_NINTENDO_OTP should depend on WII
+
+The Nintendo Wii and Wii U OTP is only present on Nintendo Wii and Wii U
+consoles.  Hence add a dependency on WII, to prevent asking the user
+about this driver when configuring a kernel without Nintendo Wii and Wii
+U console support.
+
+Fixes: 3683b761fe3a10ad ("nvmem: nintendo-otp: Add new driver for the Wii and Wii U OTP")
+Reviewed-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/01318920709dddc4d85fe895e2083ca0eee234d8.1631611652.git.geert+renesas@glider.be
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -109,6 +109,7 @@ config MTK_EFUSE
+ config NVMEM_NINTENDO_OTP
+       tristate "Nintendo Wii and Wii U OTP Support"
++      depends on WII || COMPILE_TEST
+       help
+         This is a driver exposing the OTP of a Nintendo Wii or Wii U console.
diff --git a/target/linux/generic/backport-5.10/823-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.10/823-v6.1-0001-nvmem-add-driver-handling-U-Boot-environment-variabl.patch
new file mode 100644 (file)
index 0000000..a40c61f
--- /dev/null
@@ -0,0 +1,278 @@
+From f955dc14450695564926711cf9fa8e1d5d854302 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 15 Jun 2022 21:43:00 +0200
+Subject: [PATCH] nvmem: add driver handling U-Boot environment variables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot stores its setup as environment variables. It's a list of
+key-value pairs stored on flash device with a custom header.
+
+This commit adds an NVMEM driver that:
+1. Provides NVMEM access to environment vars binary data
+2. Extracts variables as NVMEM cells
+
+Current Linux's NVMEM sysfs API allows reading whole NVMEM data block.
+It can be used by user-space tools for reading U-Boot env vars block
+without the hassle of finding its location. Parsing will still need to
+be re-done there.
+
+Kernel-parsed NVMEM cells can be read however by Linux drivers. This may
+be useful for Ethernet drivers for reading device MAC address which is
+often stored as U-Boot env variable.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+---
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -300,4 +300,17 @@ 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 OF && MTD
++      select CRC32
++      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.
++
++        Currently this drivers works only with env variables on top of MTD.
++
++        If compiled as module it will be called nvmem_u-boot-env.
++
+ endif
+--- a/drivers/nvmem/Makefile
++++ b/drivers/nvmem/Makefile
+@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM)     += nvmem-rmem.
+ 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
+--- /dev/null
++++ b/drivers/nvmem/u-boot-env.c
+@@ -0,0 +1,218 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2022 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_SINGLE,
++      U_BOOT_FORMAT_REDUNDANT,
++};
++
++struct u_boot_env {
++      struct device *dev;
++      enum u_boot_env_format format;
++
++      struct mtd_info *mtd;
++
++      /* Cells */
++      struct nvmem_cell_info *cells;
++      int ncells;
++};
++
++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;
++
++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, 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 %zu bytes\n", bytes);
++              return -EIO;
++      }
++
++      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 device *dev = priv->dev;
++      char *data = buf + data_offset;
++      char *var, *value, *eq;
++      int idx;
++
++      priv->ncells = 0;
++      for (var = data; var < data + 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 < data + 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 - 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;
++      size_t crc32_data_offset;
++      size_t crc32_data_len;
++      size_t crc32_offset;
++      size_t data_offset;
++      size_t data_len;
++      uint32_t crc32;
++      uint32_t calc;
++      size_t bytes;
++      uint8_t *buf;
++      int err;
++
++      buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
++      if (!buf) {
++              err = -ENOMEM;
++              goto err_out;
++      }
++
++      err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
++      if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
++              dev_err(dev, "Failed to read from mtd: %d\n", err);
++              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, mark);
++              data_offset = offsetof(struct u_boot_env_image_redundant, data);
++              break;
++      }
++      crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
++      crc32_data_len = priv->mtd->size - crc32_data_offset;
++      data_len = priv->mtd->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[priv->mtd->size - 1] = '\0';
++      err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
++      if (err)
++              dev_err(dev, "Failed to add cells: %d\n", err);
++
++err_kfree:
++      kfree(buf);
++err_out:
++      return err;
++}
++
++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;
++      struct u_boot_env *priv;
++      int err;
++
++      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++      priv->dev = dev;
++
++      priv->format = (uintptr_t)of_device_get_match_data(dev);
++
++      priv->mtd = of_get_mtd_device_by_node(np);
++      if (IS_ERR(priv->mtd)) {
++              dev_err_probe(dev, PTR_ERR(priv->mtd), "Failed to get %pOF MTD\n", np);
++              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->mtd->size;
++
++      return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
++}
++
++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, },
++      {},
++};
++
++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,
++      },
++};
++module_platform_driver(u_boot_env_driver);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-5.10/823-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.10/823-v6.1-0002-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch
new file mode 100644 (file)
index 0000000..3a6b76a
--- /dev/null
@@ -0,0 +1,29 @@
+From d69efcf951df4dcc74a0e1554969c533aec8aa9b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 15 Sep 2022 22:06:29 +0200
+Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+DT binding allows specifying NVMEM cells as NVMEM device (provider)
+subnodes. Looks for such subnodes when building NVMEM cells.
+
+This allows NVMEM consumers to use U-Boot environment variables.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+---
+ drivers/nvmem/u-boot-env.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u
+                       return -ENOMEM;
+               priv->cells[idx].offset = data_offset + value - data;
+               priv->cells[idx].bytes = strlen(value);
++              priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
+       }
+       if (WARN_ON(idx != priv->ncells))
diff --git a/target/linux/generic/backport-5.10/823-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.10/823-v6.1-0003-nvmem-u-boot-env-fix-crc32-casting-type.patch
new file mode 100644 (file)
index 0000000..6b40557
--- /dev/null
@@ -0,0 +1,30 @@
+From 60bbaad38109684b156e21112322e0a922f92cde Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Thu, 18 Aug 2022 06:38:37 +0200
+Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes:
+drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+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
+@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo
+               data_offset = offsetof(struct u_boot_env_image_redundant, data);
+               break;
+       }
+-      crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset));
++      crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
+       crc32_data_len = priv->mtd->size - crc32_data_offset;
+       data_len = priv->mtd->size - data_offset;
diff --git a/target/linux/generic/backport-5.10/824-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch b/target/linux/generic/backport-5.10/824-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch
new file mode 100644 (file)
index 0000000..1acc694
--- /dev/null
@@ -0,0 +1,41 @@
+From dbc2f62061c6bfba0aee93161ee3194dcee84bd0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 29 Apr 2022 17:26:46 +0100
+Subject: [PATCH] nvmem: core: support passing DT node in cell info
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some hardware may have NVMEM cells described in Device Tree using
+individual nodes. Let drivers pass such nodes to the NVMEM subsystem so
+they can be later used by NVMEM consumers.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20220429162701.2222-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c           | 1 +
+ include/linux/nvmem-consumer.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -462,6 +462,7 @@ static int nvmem_cell_info_to_nvmem_cell
+       cell->bit_offset = info->bit_offset;
+       cell->nbits = info->nbits;
++      cell->np = info->np;
+       if (cell->nbits)
+               cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
+--- a/include/linux/nvmem-consumer.h
++++ b/include/linux/nvmem-consumer.h
+@@ -25,6 +25,7 @@ struct nvmem_cell_info {
+       unsigned int            bytes;
+       unsigned int            bit_offset;
+       unsigned int            nbits;
++      struct device_node      *np;
+ };
+ /**
diff --git a/target/linux/generic/backport-5.10/825-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch b/target/linux/generic/backport-5.10/825-v6.2-0001-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch
new file mode 100644 (file)
index 0000000..69d5a1b
--- /dev/null
@@ -0,0 +1,56 @@
+From 7a69ff9c9bde03a690ea783970f664782fc303d8 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Fri, 4 Nov 2022 17:52:03 +0100
+Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant
+ u-boot-env
+
+The Western Digital MyBook Live (PowerPC 464/APM82181)
+has a set of redundant u-boot-env. Loading up the driver
+the following error:
+
+| u_boot_env: Invalid calculated CRC32: 0x4f8f2c86 (expected: 0x98b14514)
+| u_boot_env: probe of partition@1e000 failed with error -22
+
+Looking up the userspace libubootenv utilities source [0],
+it looks like the "mark" or "flag" is not part of the
+crc32 sum... which is unfortunate :(
+
+|static int libuboot_load(struct uboot_ctx *ctx)
+|{
+|[...]
+|       if (ctx->redundant) {
+|              [...]
+|               offsetdata = offsetof(struct uboot_env_redund, data);
+|              [...]                                   //-----^^
+|       }
+|       usable_envsize = ctx->size - offsetdata;
+|       buf[0] = malloc(bufsize);
+|[...]
+|      for (i = 0; i < copies; i++) {
+|              data = (uint8_t *)(buf[i] + offsetdata);
+|               uint32_t crc;
+|
+|              ret = devread(ctx, i, buf[i]);
+|              [...]
+|              crc = *(uint32_t *)(buf[i] + offsetcrc);
+|               dev->crc = crc32(0, (uint8_t *)data, usable_envsize);
+|
+
+[0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951
+Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+---
+ 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
+@@ -135,7 +135,7 @@ static int u_boot_env_parse(struct u_boo
+               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, mark);
++              crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
+               data_offset = offsetof(struct u_boot_env_image_redundant, data);
+               break;
+       }
diff --git a/target/linux/generic/backport-5.10/825-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/backport-5.10/825-v6.2-0002-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
new file mode 100644 (file)
index 0000000..7d6723b
--- /dev/null
@@ -0,0 +1,47 @@
+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
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch fixes crc32 error on Big-Endianness system by conversion of
+calculated crc32 value.
+
+Little-Endianness system:
+
+  obtained crc32: Little
+calculated crc32: Little
+
+Big-Endianness system:
+
+  obtained crc32: Little
+calculated crc32: Big
+
+log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness):
+
+[    8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88)
+[    8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22
+
+Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables")
+
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+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
+@@ -143,7 +143,7 @@ static int u_boot_env_parse(struct u_boo
+       crc32_data_len = priv->mtd->size - crc32_data_offset;
+       data_len = priv->mtd->size - data_offset;
+-      calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
++      calc = le32_to_cpu((__le32)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;
diff --git a/target/linux/generic/backport-5.10/825-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-5.10/825-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch
new file mode 100644 (file)
index 0000000..429b24f
--- /dev/null
@@ -0,0 +1,65 @@
+From 5b4eaafbeac472fc19049152f18e88aecb2b2829 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 17 Oct 2022 09:17:22 +0200
+Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They
+decided to store U-Boot environment data inside U-Boot partition and to
+use a custom header (with "uEnv" magic and env data length).
+
+Add support for Broadcom's specific binding and their custom format.
+
+Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding")
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+---
+ drivers/nvmem/u-boot-env.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -16,6 +16,7 @@
+ enum u_boot_env_format {
+       U_BOOT_FORMAT_SINGLE,
+       U_BOOT_FORMAT_REDUNDANT,
++      U_BOOT_FORMAT_BROADCOM,
+ };
+ struct u_boot_env {
+@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant {
+       uint8_t data[];
+ } __packed;
++struct u_boot_env_image_broadcom {
++      __le32 magic;
++      __le32 len;
++      __le32 crc32;
++      uint8_t data[0];
++} __packed;
++
+ static int u_boot_env_read(void *context, unsigned int offset, void *val,
+                          size_t bytes)
+ {
+@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo
+               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;
+       }
+       crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
+       crc32_data_len = priv->mtd->size - crc32_data_offset;
+@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_
+       { .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, },
+       {},
+ };
index a2dc9b90b1fc29e6541a37615de699a01cdc4c96..01bebbbab42f1bda368de5b1ffce55a2eba7164f 100644 (file)
@@ -4244,6 +4244,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
 # CONFIG_NVMEM_BCM_OCOTP is not set
 # CONFIG_NVMEM_IMX_OCOTP is not set
 # CONFIG_NVMEM_REBOOT_MODE is not set
+# CONFIG_NVMEM_RMEM is not set
 # CONFIG_NVMEM_SYSFS is not set
 # CONFIG_NVMEM_U_BOOT_ENV is not set
 # CONFIG_NVME_FC is not set