generic: 6.6: move NVMEM-on-UBI patches from pending to backports
authorDaniel Golle <daniel@makrotopia.org>
Fri, 14 Jun 2024 15:24:12 +0000 (16:24 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Sun, 16 Jun 2024 12:28:01 +0000 (13:28 +0100)
The series was merged for Linux v6.9, so move it to backports.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
19 files changed:
target/linux/generic/backport-6.6/401-v6.9-dt-bindings-mtd-add-basic-bindings-for-UBI.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/402-v6.9-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/403-v6.9-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/404-v6.9-mtd-ubi-attach-from-device-tree.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/405-v6.9-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/406-v6.9-mtd-ubi-populate-ubi-volume-fwnode.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/407-v6.9-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/408-v6.9-mtd-ubi-fix-NVMEM-over-UBI-volumes-on-32-bit-systems.patch [new file with mode: 0644]
target/linux/generic/pending-6.6/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch [deleted file]
target/linux/generic/pending-6.6/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch [deleted file]
target/linux/generic/pending-6.6/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch [deleted file]
target/linux/generic/pending-6.6/450-04-mtd-ubi-attach-from-device-tree.patch [deleted file]
target/linux/generic/pending-6.6/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch [deleted file]
target/linux/generic/pending-6.6/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch [deleted file]
target/linux/generic/pending-6.6/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch [deleted file]
target/linux/generic/pending-6.6/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
target/linux/generic/pending-6.6/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch

diff --git a/target/linux/generic/backport-6.6/401-v6.9-dt-bindings-mtd-add-basic-bindings-for-UBI.patch b/target/linux/generic/backport-6.6/401-v6.9-dt-bindings-mtd-add-basic-bindings-for-UBI.patch
new file mode 100644 (file)
index 0000000..8119948
--- /dev/null
@@ -0,0 +1,123 @@
+From 25d88bfd35bac3196eafa666e3b05033b46ffa21 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:32:00 +0000
+Subject: [PATCH 1/8] dt-bindings: mtd: add basic bindings for UBI
+
+Add basic bindings for UBI devices and volumes.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ .../bindings/mtd/partitions/linux,ubi.yaml    | 65 +++++++++++++++++++
+ .../bindings/mtd/partitions/ubi-volume.yaml   | 35 ++++++++++
+ 2 files changed, 100 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
+ create mode 100644 Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
+@@ -0,0 +1,65 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mtd/partitions/linux,ubi.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Unsorted Block Images
++
++description: |
++  UBI ("Unsorted Block Images") is a volume management system for raw
++  flash devices which manages multiple logical volumes on a single
++  physical flash device and spreads the I/O load (i.e wear-leveling)
++  across the whole flash chip.
++
++maintainers:
++  - Daniel Golle <daniel@makrotopia.org>
++
++allOf:
++  - $ref: partition.yaml#
++
++properties:
++  compatible:
++    const: linux,ubi
++
++  volumes:
++    type: object
++    description: UBI Volumes
++
++    patternProperties:
++      "^ubi-volume-.*$":
++        $ref: /schemas/mtd/partitions/ubi-volume.yaml#
++
++    unevaluatedProperties: false
++
++required:
++  - compatible
++
++unevaluatedProperties: false
++
++examples:
++  - |
++    partitions {
++        compatible = "fixed-partitions";
++        #address-cells = <1>;
++        #size-cells = <1>;
++
++        partition@0 {
++            reg = <0x0 0x100000>;
++            label = "bootloader";
++            read-only;
++        };
++
++        partition@100000 {
++            reg = <0x100000 0x1ff00000>;
++            label = "ubi";
++            compatible = "linux,ubi";
++
++            volumes {
++                ubi-volume-caldata {
++                    volid = <2>;
++                    volname = "rf";
++                };
++            };
++        };
++    };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
+@@ -0,0 +1,35 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mtd/partitions/ubi-volume.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: UBI volume
++
++description: |
++  This binding describes a single UBI volume. Volumes can be matches either
++  by their ID or their name, or both.
++
++maintainers:
++  - Daniel Golle <daniel@makrotopia.org>
++
++properties:
++  volid:
++    $ref: /schemas/types.yaml#/definitions/uint32
++    description:
++      Match UBI volume ID
++
++  volname:
++    $ref: /schemas/types.yaml#/definitions/string
++    description:
++      Match UBI volume ID
++
++anyOf:
++  - required:
++      - volid
++
++  - required:
++      - volname
++
++# This is a generic file other binding inherit from and extend
++additionalProperties: true
diff --git a/target/linux/generic/backport-6.6/402-v6.9-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch b/target/linux/generic/backport-6.6/402-v6.9-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch
new file mode 100644 (file)
index 0000000..a394338
--- /dev/null
@@ -0,0 +1,50 @@
+From 95b113222b5164ac0887eb5c514ff3970a0136f0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:32:11 +0000
+Subject: [PATCH 2/8] dt-bindings: mtd: ubi-volume: allow UBI volumes to
+ provide NVMEM
+
+UBI volumes may be used to contain NVMEM bits, typically device MAC
+addresses or wireless radio calibration data.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ .../devicetree/bindings/mtd/partitions/linux,ubi.yaml  | 10 ++++++++++
+ .../devicetree/bindings/mtd/partitions/ubi-volume.yaml |  5 +++++
+ 2 files changed, 15 insertions(+)
+
+--- a/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
++++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
+@@ -59,6 +59,16 @@ examples:
+                 ubi-volume-caldata {
+                     volid = <2>;
+                     volname = "rf";
++
++                    nvmem-layout {
++                        compatible = "fixed-layout";
++                        #address-cells = <1>;
++                        #size-cells = <1>;
++
++                        eeprom@0 {
++                            reg = <0x0 0x1000>;
++                        };
++                    };
+                 };
+             };
+         };
+--- a/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
++++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
+@@ -24,6 +24,11 @@ properties:
+     description:
+       Match UBI volume ID
++  nvmem-layout:
++    $ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
++    description:
++      This container may reference an NVMEM layout parser.
++
+ anyOf:
+   - required:
+       - volid
diff --git a/target/linux/generic/backport-6.6/403-v6.9-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch b/target/linux/generic/backport-6.6/403-v6.9-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch
new file mode 100644 (file)
index 0000000..f89330c
--- /dev/null
@@ -0,0 +1,285 @@
+From 2bba1cdcfcd2907d0696cc0139f1bd078d36ee81 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:32:35 +0000
+Subject: [PATCH 3/8] mtd: ubi: block: use notifier to create ubiblock from
+ parameter
+
+Use UBI_VOLUME_ADDED notification to create ubiblock device specified
+on kernel cmdline or module parameter.
+This makes thing more simple and has the advantage that ubiblock devices
+on volumes which are not present at the time the ubi module is probed
+will still be created.
+
+Suggested-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/block.c | 136 ++++++++++++++++++++--------------------
+ drivers/mtd/ubi/kapi.c  |  54 +++++++++++-----
+ drivers/mtd/ubi/ubi.h   |   1 +
+ 3 files changed, 106 insertions(+), 85 deletions(-)
+
+--- a/drivers/mtd/ubi/block.c
++++ b/drivers/mtd/ubi/block.c
+@@ -65,10 +65,10 @@ struct ubiblock_pdu {
+ };
+ /* Numbers of elements set in the @ubiblock_param array */
+-static int ubiblock_devs __initdata;
++static int ubiblock_devs;
+ /* MTD devices specification parameters */
+-static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata;
++static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES];
+ struct ubiblock {
+       struct ubi_volume_desc *desc;
+@@ -532,6 +532,70 @@ static int ubiblock_resize(struct ubi_vo
+       return 0;
+ }
++static bool
++match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
++{
++      int err, len, cur_ubi_num, cur_vol_id;
++
++      if (ubi_num == -1) {
++              /* No ubi num, name must be a vol device path */
++              err = ubi_get_num_by_path(name, &cur_ubi_num, &cur_vol_id);
++              if (err || vi->ubi_num != cur_ubi_num || vi->vol_id != cur_vol_id)
++                      return false;
++
++              return true;
++      }
++
++      if (vol_id == -1) {
++              /* Got ubi_num, but no vol_id, name must be volume name */
++              if (vi->ubi_num != ubi_num)
++                      return false;
++
++              len = strnlen(name, UBI_VOL_NAME_MAX + 1);
++              if (len < 1 || vi->name_len != len)
++                      return false;
++
++              if (strcmp(name, vi->name))
++                      return false;
++
++              return true;
++      }
++
++      if (vi->ubi_num != ubi_num)
++              return false;
++
++      if (vi->vol_id != vol_id)
++              return false;
++
++      return true;
++}
++
++static void
++ubiblock_create_from_param(struct ubi_volume_info *vi)
++{
++      int i, ret = 0;
++      struct ubiblock_param *p;
++
++      /*
++       * Iterate over ubiblock cmdline parameters. If a parameter matches the
++       * newly added volume create the ubiblock device for it.
++       */
++      for (i = 0; i < ubiblock_devs; i++) {
++              p = &ubiblock_param[i];
++
++              if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
++                      continue;
++
++              ret = ubiblock_create(vi);
++              if (ret) {
++                      pr_err(
++                             "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
++                             vi->name, p->ubi_num, p->vol_id, ret);
++              }
++              break;
++      }
++}
++
+ static int ubiblock_notify(struct notifier_block *nb,
+                        unsigned long notification_type, void *ns_ptr)
+ {
+@@ -539,10 +603,7 @@ static int ubiblock_notify(struct notifi
+       switch (notification_type) {
+       case UBI_VOLUME_ADDED:
+-              /*
+-               * We want to enforce explicit block device creation for
+-               * volumes, so when a volume is added we do nothing.
+-               */
++              ubiblock_create_from_param(&nt->vi);
+               break;
+       case UBI_VOLUME_REMOVED:
+               ubiblock_remove(&nt->vi);
+@@ -568,56 +629,6 @@ static struct notifier_block ubiblock_no
+       .notifier_call = ubiblock_notify,
+ };
+-static struct ubi_volume_desc * __init
+-open_volume_desc(const char *name, int ubi_num, int vol_id)
+-{
+-      if (ubi_num == -1)
+-              /* No ubi num, name must be a vol device path */
+-              return ubi_open_volume_path(name, UBI_READONLY);
+-      else if (vol_id == -1)
+-              /* No vol_id, must be vol_name */
+-              return ubi_open_volume_nm(ubi_num, name, UBI_READONLY);
+-      else
+-              return ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
+-}
+-
+-static void __init ubiblock_create_from_param(void)
+-{
+-      int i, ret = 0;
+-      struct ubiblock_param *p;
+-      struct ubi_volume_desc *desc;
+-      struct ubi_volume_info vi;
+-
+-      /*
+-       * If there is an error creating one of the ubiblocks, continue on to
+-       * create the following ubiblocks. This helps in a circumstance where
+-       * the kernel command-line specifies multiple block devices and some
+-       * may be broken, but we still want the working ones to come up.
+-       */
+-      for (i = 0; i < ubiblock_devs; i++) {
+-              p = &ubiblock_param[i];
+-
+-              desc = open_volume_desc(p->name, p->ubi_num, p->vol_id);
+-              if (IS_ERR(desc)) {
+-                      pr_err(
+-                             "UBI: block: can't open volume on ubi%d_%d, err=%ld\n",
+-                             p->ubi_num, p->vol_id, PTR_ERR(desc));
+-                      continue;
+-              }
+-
+-              ubi_get_volume_info(desc, &vi);
+-              ubi_close_volume(desc);
+-
+-              ret = ubiblock_create(&vi);
+-              if (ret) {
+-                      pr_err(
+-                             "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
+-                             vi.name, p->ubi_num, p->vol_id, ret);
+-                      continue;
+-              }
+-      }
+-}
+-
+ static void ubiblock_remove_all(void)
+ {
+       struct ubiblock *next;
+@@ -643,18 +654,7 @@ int __init ubiblock_init(void)
+       if (ubiblock_major < 0)
+               return ubiblock_major;
+-      /*
+-       * Attach block devices from 'block=' module param.
+-       * Even if one block device in the param list fails to come up,
+-       * still allow the module to load and leave any others up.
+-       */
+-      ubiblock_create_from_param();
+-
+-      /*
+-       * Block devices are only created upon user requests, so we ignore
+-       * existing volumes.
+-       */
+-      ret = ubi_register_volume_notifier(&ubiblock_notifier, 1);
++      ret = ubi_register_volume_notifier(&ubiblock_notifier, 0);
+       if (ret)
+               goto err_unreg;
+       return 0;
+--- a/drivers/mtd/ubi/kapi.c
++++ b/drivers/mtd/ubi/kapi.c
+@@ -280,6 +280,41 @@ struct ubi_volume_desc *ubi_open_volume_
+ EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
+ /**
++ * ubi_get_num_by_path - get UBI device and volume number from device path
++ * @pathname: volume character device node path
++ * @ubi_num: pointer to UBI device number to be set
++ * @vol_id: pointer to UBI volume ID to be set
++ *
++ * Returns 0 on success and sets ubi_num and vol_id, returns error otherwise.
++ */
++int ubi_get_num_by_path(const char *pathname, int *ubi_num, int *vol_id)
++{
++      int error;
++      struct path path;
++      struct kstat stat;
++
++      error = kern_path(pathname, LOOKUP_FOLLOW, &path);
++      if (error)
++              return error;
++
++      error = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
++      path_put(&path);
++      if (error)
++              return error;
++
++      if (!S_ISCHR(stat.mode))
++              return -EINVAL;
++
++      *ubi_num = ubi_major2num(MAJOR(stat.rdev));
++      *vol_id = MINOR(stat.rdev) - 1;
++
++      if (*vol_id < 0 || *ubi_num < 0)
++              return -ENODEV;
++
++      return 0;
++}
++
++/**
+  * ubi_open_volume_path - open UBI volume by its character device node path.
+  * @pathname: volume character device node path
+  * @mode: open mode
+@@ -290,32 +325,17 @@ EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
+ struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
+ {
+       int error, ubi_num, vol_id;
+-      struct path path;
+-      struct kstat stat;
+       dbg_gen("open volume %s, mode %d", pathname, mode);
+       if (!pathname || !*pathname)
+               return ERR_PTR(-EINVAL);
+-      error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+-      if (error)
+-              return ERR_PTR(error);
+-
+-      error = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
+-      path_put(&path);
++      error = ubi_get_num_by_path(pathname, &ubi_num, &vol_id);
+       if (error)
+               return ERR_PTR(error);
+-      if (!S_ISCHR(stat.mode))
+-              return ERR_PTR(-EINVAL);
+-
+-      ubi_num = ubi_major2num(MAJOR(stat.rdev));
+-      vol_id = MINOR(stat.rdev) - 1;
+-
+-      if (vol_id >= 0 && ubi_num >= 0)
+-              return ubi_open_volume(ubi_num, vol_id, mode);
+-      return ERR_PTR(-ENODEV);
++      return ubi_open_volume(ubi_num, vol_id, mode);
+ }
+ EXPORT_SYMBOL_GPL(ubi_open_volume_path);
+--- a/drivers/mtd/ubi/ubi.h
++++ b/drivers/mtd/ubi/ubi.h
+@@ -956,6 +956,7 @@ void ubi_free_internal_volumes(struct ub
+ void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
+ void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
+                           struct ubi_volume_info *vi);
++int ubi_get_num_by_path(const char *pathname, int *ubi_num, int *vol_id);
+ /* scan.c */
+ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
+                     int pnum, const struct ubi_vid_hdr *vid_hdr);
diff --git a/target/linux/generic/backport-6.6/404-v6.9-mtd-ubi-attach-from-device-tree.patch b/target/linux/generic/backport-6.6/404-v6.9-mtd-ubi-attach-from-device-tree.patch
new file mode 100644 (file)
index 0000000..ec7b6c3
--- /dev/null
@@ -0,0 +1,205 @@
+From 6e331888643887ce85657527bc03f97d46235e71 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:33:14 +0000
+Subject: [PATCH 4/8] mtd: ubi: attach from device tree
+
+Introduce device tree compatible 'linux,ubi' and attach compatible MTD
+devices using the MTD add notifier. This is needed for a UBI device to
+be available early at boot (and not only after late_initcall), so
+volumes on them can be used eg. as NVMEM providers for other drivers.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/build.c | 135 ++++++++++++++++++++++++++++------------
+ 1 file changed, 96 insertions(+), 39 deletions(-)
+
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -27,6 +27,7 @@
+ #include <linux/log2.h>
+ #include <linux/kthread.h>
+ #include <linux/kernel.h>
++#include <linux/of.h>
+ #include <linux/slab.h>
+ #include <linux/major.h>
+ #include "ubi.h"
+@@ -1214,43 +1215,43 @@ static struct mtd_info * __init open_mtd
+       return mtd;
+ }
+-static int __init ubi_init(void)
++static void ubi_notify_add(struct mtd_info *mtd)
+ {
+-      int err, i, k;
++      struct device_node *np = mtd_get_of_node(mtd);
++      int err;
+-      /* Ensure that EC and VID headers have correct size */
+-      BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
+-      BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
++      if (!of_device_is_compatible(np, "linux,ubi"))
++              return;
+-      if (mtd_devs > UBI_MAX_DEVICES) {
+-              pr_err("UBI error: too many MTD devices, maximum is %d\n",
+-                     UBI_MAX_DEVICES);
+-              return -EINVAL;
+-      }
++      /*
++       * we are already holding &mtd_table_mutex, but still need
++       * to bump refcount
++       */
++      err = __get_mtd_device(mtd);
++      if (err)
++              return;
+-      /* Create base sysfs directory and sysfs files */
+-      err = class_register(&ubi_class);
++      /* called while holding mtd_table_mutex */
++      mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING);
++      err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false);
++      mutex_unlock(&ubi_devices_mutex);
+       if (err < 0)
+-              return err;
+-
+-      err = misc_register(&ubi_ctrl_cdev);
+-      if (err) {
+-              pr_err("UBI error: cannot register device\n");
+-              goto out;
+-      }
++              __put_mtd_device(mtd);
++}
+-      ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
+-                                            sizeof(struct ubi_wl_entry),
+-                                            0, 0, NULL);
+-      if (!ubi_wl_entry_slab) {
+-              err = -ENOMEM;
+-              goto out_dev_unreg;
+-      }
++static void ubi_notify_remove(struct mtd_info *mtd)
++{
++      /* do nothing for now */
++}
+-      err = ubi_debugfs_init();
+-      if (err)
+-              goto out_slab;
++static struct mtd_notifier ubi_mtd_notifier = {
++      .add = ubi_notify_add,
++      .remove = ubi_notify_remove,
++};
++static int __init ubi_init_attach(void)
++{
++      int err, i, k;
+       /* Attach MTD devices */
+       for (i = 0; i < mtd_devs; i++) {
+@@ -1298,25 +1299,79 @@ static int __init ubi_init(void)
+               }
+       }
++      return 0;
++
++out_detach:
++      for (k = 0; k < i; k++)
++              if (ubi_devices[k]) {
++                      mutex_lock(&ubi_devices_mutex);
++                      ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
++                      mutex_unlock(&ubi_devices_mutex);
++              }
++      return err;
++}
++#ifndef CONFIG_MTD_UBI_MODULE
++late_initcall(ubi_init_attach);
++#endif
++
++static int __init ubi_init(void)
++{
++      int err;
++
++      /* Ensure that EC and VID headers have correct size */
++      BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
++      BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
++
++      if (mtd_devs > UBI_MAX_DEVICES) {
++              pr_err("UBI error: too many MTD devices, maximum is %d\n",
++                     UBI_MAX_DEVICES);
++              return -EINVAL;
++      }
++
++      /* Create base sysfs directory and sysfs files */
++      err = class_register(&ubi_class);
++      if (err < 0)
++              return err;
++
++      err = misc_register(&ubi_ctrl_cdev);
++      if (err) {
++              pr_err("UBI error: cannot register device\n");
++              goto out;
++      }
++
++      ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
++                                            sizeof(struct ubi_wl_entry),
++                                            0, 0, NULL);
++      if (!ubi_wl_entry_slab) {
++              err = -ENOMEM;
++              goto out_dev_unreg;
++      }
++
++      err = ubi_debugfs_init();
++      if (err)
++              goto out_slab;
++
+       err = ubiblock_init();
+       if (err) {
+               pr_err("UBI error: block: cannot initialize, error %d\n", err);
+               /* See comment above re-ubi_is_module(). */
+               if (ubi_is_module())
+-                      goto out_detach;
++                      goto out_slab;
++      }
++
++      register_mtd_user(&ubi_mtd_notifier);
++
++      if (ubi_is_module()) {
++              err = ubi_init_attach();
++              if (err)
++                      goto out_mtd_notifier;
+       }
+       return 0;
+-out_detach:
+-      for (k = 0; k < i; k++)
+-              if (ubi_devices[k]) {
+-                      mutex_lock(&ubi_devices_mutex);
+-                      ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
+-                      mutex_unlock(&ubi_devices_mutex);
+-              }
+-      ubi_debugfs_exit();
++out_mtd_notifier:
++      unregister_mtd_user(&ubi_mtd_notifier);
+ out_slab:
+       kmem_cache_destroy(ubi_wl_entry_slab);
+ out_dev_unreg:
+@@ -1326,13 +1381,15 @@ out:
+       pr_err("UBI error: cannot initialize UBI, error %d\n", err);
+       return err;
+ }
+-late_initcall(ubi_init);
++device_initcall(ubi_init);
++
+ static void __exit ubi_exit(void)
+ {
+       int i;
+       ubiblock_exit();
++      unregister_mtd_user(&ubi_mtd_notifier);
+       for (i = 0; i < UBI_MAX_DEVICES; i++)
+               if (ubi_devices[i]) {
diff --git a/target/linux/generic/backport-6.6/405-v6.9-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch b/target/linux/generic/backport-6.6/405-v6.9-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch
new file mode 100644 (file)
index 0000000..fb76ffc
--- /dev/null
@@ -0,0 +1,180 @@
+From 924731fbed3247e3b82b8ab17db587ee28c2e781 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:33:24 +0000
+Subject: [PATCH 5/8] mtd: ubi: introduce pre-removal notification for UBI
+ volumes
+
+Introduce a new notification type UBI_VOLUME_SHUTDOWN to inform users
+that a volume is just about to be removed.
+This is needed because users (such as the NVMEM subsystem) expect that
+at the time their removal function is called, the parenting device is
+still available (for removal of sysfs nodes, for example, in case of
+NVMEM which otherwise WARNs on volume removal).
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/build.c | 19 ++++++++++++++-----
+ drivers/mtd/ubi/kapi.c  |  2 +-
+ drivers/mtd/ubi/ubi.h   |  2 ++
+ drivers/mtd/ubi/vmt.c   | 17 +++++++++++++++--
+ include/linux/mtd/ubi.h |  2 ++
+ 5 files changed, 34 insertions(+), 8 deletions(-)
+
+--- a/drivers/mtd/ubi/build.c
++++ b/drivers/mtd/ubi/build.c
+@@ -91,7 +91,7 @@ static struct ubi_device *ubi_devices[UB
+ /* Serializes UBI devices creations and removals */
+ DEFINE_MUTEX(ubi_devices_mutex);
+-/* Protects @ubi_devices and @ubi->ref_count */
++/* Protects @ubi_devices, @ubi->ref_count and @ubi->is_dead */
+ static DEFINE_SPINLOCK(ubi_devices_lock);
+ /* "Show" method for files in '/<sysfs>/class/ubi/' */
+@@ -259,6 +259,9 @@ struct ubi_device *ubi_get_device(int ub
+       spin_lock(&ubi_devices_lock);
+       ubi = ubi_devices[ubi_num];
++      if (ubi && ubi->is_dead)
++              ubi = NULL;
++
+       if (ubi) {
+               ubi_assert(ubi->ref_count >= 0);
+               ubi->ref_count += 1;
+@@ -296,7 +299,7 @@ struct ubi_device *ubi_get_by_major(int
+       spin_lock(&ubi_devices_lock);
+       for (i = 0; i < UBI_MAX_DEVICES; i++) {
+               ubi = ubi_devices[i];
+-              if (ubi && MAJOR(ubi->cdev.dev) == major) {
++              if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
+                       ubi_assert(ubi->ref_count >= 0);
+                       ubi->ref_count += 1;
+                       get_device(&ubi->dev);
+@@ -325,7 +328,7 @@ int ubi_major2num(int major)
+       for (i = 0; i < UBI_MAX_DEVICES; i++) {
+               struct ubi_device *ubi = ubi_devices[i];
+-              if (ubi && MAJOR(ubi->cdev.dev) == major) {
++              if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
+                       ubi_num = ubi->ubi_num;
+                       break;
+               }
+@@ -512,7 +515,7 @@ static void ubi_free_volumes_from(struct
+       int i;
+       for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
+-              if (!ubi->volumes[i])
++              if (!ubi->volumes[i] || ubi->volumes[i]->is_dead)
+                       continue;
+               ubi_eba_replace_table(ubi->volumes[i], NULL);
+               ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
+@@ -1094,7 +1097,6 @@ int ubi_detach_mtd_dev(int ubi_num, int
+               return -EINVAL;
+       spin_lock(&ubi_devices_lock);
+-      put_device(&ubi->dev);
+       ubi->ref_count -= 1;
+       if (ubi->ref_count) {
+               if (!anyway) {
+@@ -1105,6 +1107,13 @@ int ubi_detach_mtd_dev(int ubi_num, int
+               ubi_err(ubi, "%s reference count %d, destroy anyway",
+                       ubi->ubi_name, ubi->ref_count);
+       }
++      ubi->is_dead = true;
++      spin_unlock(&ubi_devices_lock);
++
++      ubi_notify_all(ubi, UBI_VOLUME_SHUTDOWN, NULL);
++
++      spin_lock(&ubi_devices_lock);
++      put_device(&ubi->dev);
+       ubi_devices[ubi_num] = NULL;
+       spin_unlock(&ubi_devices_lock);
+--- a/drivers/mtd/ubi/kapi.c
++++ b/drivers/mtd/ubi/kapi.c
+@@ -152,7 +152,7 @@ struct ubi_volume_desc *ubi_open_volume(
+       spin_lock(&ubi->volumes_lock);
+       vol = ubi->volumes[vol_id];
+-      if (!vol)
++      if (!vol || vol->is_dead)
+               goto out_unlock;
+       err = -EBUSY;
+--- a/drivers/mtd/ubi/ubi.h
++++ b/drivers/mtd/ubi/ubi.h
+@@ -345,6 +345,7 @@ struct ubi_volume {
+       int writers;
+       int exclusive;
+       int metaonly;
++      bool is_dead;
+       int reserved_pebs;
+       int vol_type;
+@@ -564,6 +565,7 @@ struct ubi_device {
+       spinlock_t volumes_lock;
+       int ref_count;
+       int image_seq;
++      bool is_dead;
+       int rsvd_pebs;
+       int avail_pebs;
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -59,7 +59,7 @@ static ssize_t vol_attribute_show(struct
+       struct ubi_device *ubi = vol->ubi;
+       spin_lock(&ubi->volumes_lock);
+-      if (!ubi->volumes[vol->vol_id]) {
++      if (!ubi->volumes[vol->vol_id] || ubi->volumes[vol->vol_id]->is_dead) {
+               spin_unlock(&ubi->volumes_lock);
+               return -ENODEV;
+       }
+@@ -189,7 +189,7 @@ int ubi_create_volume(struct ubi_device
+       /* Ensure that the name is unique */
+       for (i = 0; i < ubi->vtbl_slots; i++)
+-              if (ubi->volumes[i] &&
++              if (ubi->volumes[i] && !ubi->volumes[i]->is_dead &&
+                   ubi->volumes[i]->name_len == req->name_len &&
+                   !strcmp(ubi->volumes[i]->name, req->name)) {
+                       ubi_err(ubi, "volume \"%s\" exists (ID %d)",
+@@ -352,6 +352,19 @@ int ubi_remove_volume(struct ubi_volume_
+               err = -EBUSY;
+               goto out_unlock;
+       }
++
++      /*
++       * Mark volume as dead at this point to prevent that anyone
++       * can take a reference to the volume from now on.
++       * This is necessary as we have to release the spinlock before
++       * calling ubi_volume_notify.
++       */
++      vol->is_dead = true;
++      spin_unlock(&ubi->volumes_lock);
++
++      ubi_volume_notify(ubi, vol, UBI_VOLUME_SHUTDOWN);
++
++      spin_lock(&ubi->volumes_lock);
+       ubi->volumes[vol_id] = NULL;
+       spin_unlock(&ubi->volumes_lock);
+--- a/include/linux/mtd/ubi.h
++++ b/include/linux/mtd/ubi.h
+@@ -192,6 +192,7 @@ struct ubi_device_info {
+  *                    or a volume was removed)
+  * @UBI_VOLUME_RESIZED: a volume has been re-sized
+  * @UBI_VOLUME_RENAMED: a volume has been re-named
++ * @UBI_VOLUME_SHUTDOWN: a volume is going to removed, shutdown users
+  * @UBI_VOLUME_UPDATED: data has been written to a volume
+  *
+  * These constants define which type of event has happened when a volume
+@@ -202,6 +203,7 @@ enum {
+       UBI_VOLUME_REMOVED,
+       UBI_VOLUME_RESIZED,
+       UBI_VOLUME_RENAMED,
++      UBI_VOLUME_SHUTDOWN,
+       UBI_VOLUME_UPDATED,
+ };
diff --git a/target/linux/generic/backport-6.6/406-v6.9-mtd-ubi-populate-ubi-volume-fwnode.patch b/target/linux/generic/backport-6.6/406-v6.9-mtd-ubi-populate-ubi-volume-fwnode.patch
new file mode 100644 (file)
index 0000000..232e74d
--- /dev/null
@@ -0,0 +1,66 @@
+From 1c54542170819e36baa43c17ca55bb3d7da89a53 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:33:38 +0000
+Subject: [PATCH 6/8] mtd: ubi: populate ubi volume fwnode
+
+Look for the 'volumes' subnode of an MTD partition attached to a UBI
+device and attach matching child nodes to UBI volumes.
+This allows UBI volumes to be referenced in device tree, e.g. for use
+as NVMEM providers.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/vmt.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/drivers/mtd/ubi/vmt.c
++++ b/drivers/mtd/ubi/vmt.c
+@@ -124,6 +124,31 @@ static void vol_release(struct device *d
+       kfree(vol);
+ }
++static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol)
++{
++      struct fwnode_handle *fw_vols, *fw_vol;
++      const char *volname;
++      u32 volid;
++
++      fw_vols = device_get_named_child_node(vol->dev.parent->parent, "volumes");
++      if (!fw_vols)
++              return NULL;
++
++      fwnode_for_each_child_node(fw_vols, fw_vol) {
++              if (!fwnode_property_read_string(fw_vol, "volname", &volname) &&
++                  strncmp(volname, vol->name, vol->name_len))
++                      continue;
++
++              if (!fwnode_property_read_u32(fw_vol, "volid", &volid) &&
++                  vol->vol_id != volid)
++                      continue;
++
++              return fw_vol;
++      }
++
++      return NULL;
++}
++
+ /**
+  * ubi_create_volume - create volume.
+  * @ubi: UBI device description object
+@@ -223,6 +248,7 @@ int ubi_create_volume(struct ubi_device
+       vol->name_len  = req->name_len;
+       memcpy(vol->name, req->name, vol->name_len);
+       vol->ubi = ubi;
++      device_set_node(&vol->dev, find_volume_fwnode(vol));
+       /*
+        * Finish all pending erases because there may be some LEBs belonging
+@@ -605,6 +631,7 @@ int ubi_add_volume(struct ubi_device *ub
+       vol->dev.class = &ubi_class;
+       vol->dev.groups = volume_dev_groups;
+       dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
++      device_set_node(&vol->dev, find_volume_fwnode(vol));
+       err = device_register(&vol->dev);
+       if (err) {
+               cdev_del(&vol->cdev);
diff --git a/target/linux/generic/backport-6.6/407-v6.9-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch b/target/linux/generic/backport-6.6/407-v6.9-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch
new file mode 100644 (file)
index 0000000..18fd1fb
--- /dev/null
@@ -0,0 +1,244 @@
+From 15fc7dc926c91c871f6c0305b2938dbdeb14203b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 19 Dec 2023 02:33:48 +0000
+Subject: [PATCH 7/8] mtd: ubi: provide NVMEM layer over UBI volumes
+
+In an ideal world we would like UBI to be used where ever possible on a
+NAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it
+is possible to achieve an (almost-)all-UBI flash layout. Hence the need
+for a way to also use UBI volumes to store board-level constants, such
+as MAC addresses and calibration data of wireless interfaces.
+
+Add UBI volume NVMEM driver module exposing UBI volumes as NVMEM
+providers. Allow UBI devices to have a "volumes" firmware subnode with
+volumes which may be compatible with "nvmem-cells".
+Access to UBI volumes via the NVMEM interface at this point is
+read-only, and it is slow, opening and closing the UBI volume for each
+access due to limitations of the NVMEM provider API.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/Kconfig  |  12 +++
+ drivers/mtd/ubi/Makefile |   1 +
+ drivers/mtd/ubi/nvmem.c  | 188 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 201 insertions(+)
+ create mode 100644 drivers/mtd/ubi/nvmem.c
+
+--- a/drivers/mtd/ubi/Kconfig
++++ b/drivers/mtd/ubi/Kconfig
+@@ -104,4 +104,16 @@ config MTD_UBI_BLOCK
+          If in doubt, say "N".
++config MTD_UBI_NVMEM
++      tristate "UBI virtual NVMEM"
++      default n
++      depends on NVMEM
++      help
++         This option enabled an additional driver exposing UBI volumes as NVMEM
++         providers, intended for platforms where UBI is part of the firmware
++         specification and used to store also e.g. MAC addresses or board-
++         specific Wi-Fi calibration data.
++
++         If in doubt, say "N".
++
+ endif # MTD_UBI
+--- a/drivers/mtd/ubi/Makefile
++++ b/drivers/mtd/ubi/Makefile
+@@ -7,3 +7,4 @@ ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap
+ ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o
+ obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
++obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o
+--- /dev/null
++++ b/drivers/mtd/ubi/nvmem.c
+@@ -0,0 +1,188 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
++ */
++
++/* UBI NVMEM provider */
++#include "ubi.h"
++#include <linux/nvmem-provider.h>
++#include <asm/div64.h>
++
++/* List of all NVMEM devices */
++static LIST_HEAD(nvmem_devices);
++static DEFINE_MUTEX(devices_mutex);
++
++struct ubi_nvmem {
++      struct nvmem_device *nvmem;
++      int ubi_num;
++      int vol_id;
++      int usable_leb_size;
++      struct list_head list;
++};
++
++static int ubi_nvmem_reg_read(void *priv, unsigned int from,
++                            void *val, size_t bytes)
++{
++      int err = 0, lnum = from, offs, bytes_left = bytes, to_read;
++      struct ubi_nvmem *unv = priv;
++      struct ubi_volume_desc *desc;
++
++      desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
++      if (IS_ERR(desc))
++              return PTR_ERR(desc);
++
++      offs = do_div(lnum, unv->usable_leb_size);
++      while (bytes_left) {
++              to_read = unv->usable_leb_size - offs;
++
++              if (to_read > bytes_left)
++                      to_read = bytes_left;
++
++              err = ubi_read(desc, lnum, val, offs, to_read);
++              if (err)
++                      break;
++
++              lnum += 1;
++              offs = 0;
++              bytes_left -= to_read;
++              val += to_read;
++      }
++      ubi_close_volume(desc);
++
++      if (err)
++              return err;
++
++      return bytes_left == 0 ? 0 : -EIO;
++}
++
++static int ubi_nvmem_add(struct ubi_volume_info *vi)
++{
++      struct device_node *np = dev_of_node(vi->dev);
++      struct nvmem_config config = {};
++      struct ubi_nvmem *unv;
++      int ret;
++
++      if (!np)
++              return 0;
++
++      if (!of_get_child_by_name(np, "nvmem-layout"))
++              return 0;
++
++      if (WARN_ON_ONCE(vi->usable_leb_size <= 0) ||
++          WARN_ON_ONCE(vi->size <= 0))
++              return -EINVAL;
++
++      unv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL);
++      if (!unv)
++              return -ENOMEM;
++
++      config.id = NVMEM_DEVID_NONE;
++      config.dev = vi->dev;
++      config.name = dev_name(vi->dev);
++      config.owner = THIS_MODULE;
++      config.priv = unv;
++      config.reg_read = ubi_nvmem_reg_read;
++      config.size = vi->usable_leb_size * vi->size;
++      config.word_size = 1;
++      config.stride = 1;
++      config.read_only = true;
++      config.root_only = true;
++      config.ignore_wp = true;
++      config.of_node = np;
++
++      unv->ubi_num = vi->ubi_num;
++      unv->vol_id = vi->vol_id;
++      unv->usable_leb_size = vi->usable_leb_size;
++      unv->nvmem = nvmem_register(&config);
++      if (IS_ERR(unv->nvmem)) {
++              ret = dev_err_probe(vi->dev, PTR_ERR(unv->nvmem),
++                                  "Failed to register NVMEM device\n");
++              kfree(unv);
++              return ret;
++      }
++
++      mutex_lock(&devices_mutex);
++      list_add_tail(&unv->list, &nvmem_devices);
++      mutex_unlock(&devices_mutex);
++
++      return 0;
++}
++
++static void ubi_nvmem_remove(struct ubi_volume_info *vi)
++{
++      struct ubi_nvmem *unv_c, *unv = NULL;
++
++      mutex_lock(&devices_mutex);
++      list_for_each_entry(unv_c, &nvmem_devices, list)
++              if (unv_c->ubi_num == vi->ubi_num && unv_c->vol_id == vi->vol_id) {
++                      unv = unv_c;
++                      break;
++              }
++
++      if (!unv) {
++              mutex_unlock(&devices_mutex);
++              return;
++      }
++
++      list_del(&unv->list);
++      mutex_unlock(&devices_mutex);
++      nvmem_unregister(unv->nvmem);
++      kfree(unv);
++}
++
++/**
++ * nvmem_notify - UBI notification handler.
++ * @nb: registered notifier block
++ * @l: notification type
++ * @ns_ptr: pointer to the &struct ubi_notification object
++ */
++static int nvmem_notify(struct notifier_block *nb, unsigned long l,
++                       void *ns_ptr)
++{
++      struct ubi_notification *nt = ns_ptr;
++
++      switch (l) {
++      case UBI_VOLUME_RESIZED:
++              ubi_nvmem_remove(&nt->vi);
++              fallthrough;
++      case UBI_VOLUME_ADDED:
++              ubi_nvmem_add(&nt->vi);
++              break;
++      case UBI_VOLUME_SHUTDOWN:
++              ubi_nvmem_remove(&nt->vi);
++              break;
++      default:
++              break;
++      }
++      return NOTIFY_OK;
++}
++
++static struct notifier_block nvmem_notifier = {
++      .notifier_call = nvmem_notify,
++};
++
++static int __init ubi_nvmem_init(void)
++{
++      return ubi_register_volume_notifier(&nvmem_notifier, 0);
++}
++
++static void __exit ubi_nvmem_exit(void)
++{
++      struct ubi_nvmem *unv, *tmp;
++
++      mutex_lock(&devices_mutex);
++      list_for_each_entry_safe(unv, tmp, &nvmem_devices, list) {
++              nvmem_unregister(unv->nvmem);
++              list_del(&unv->list);
++              kfree(unv);
++      }
++      mutex_unlock(&devices_mutex);
++
++      ubi_unregister_volume_notifier(&nvmem_notifier);
++}
++
++module_init(ubi_nvmem_init);
++module_exit(ubi_nvmem_exit);
++MODULE_DESCRIPTION("NVMEM layer over UBI volumes");
++MODULE_AUTHOR("Daniel Golle");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/backport-6.6/408-v6.9-mtd-ubi-fix-NVMEM-over-UBI-volumes-on-32-bit-systems.patch b/target/linux/generic/backport-6.6/408-v6.9-mtd-ubi-fix-NVMEM-over-UBI-volumes-on-32-bit-systems.patch
new file mode 100644 (file)
index 0000000..8ce2b46
--- /dev/null
@@ -0,0 +1,34 @@
+From 04231c61dcd51db0f12061e49bb761b197109f2f Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Thu, 29 Feb 2024 03:47:24 +0000
+Subject: [PATCH 8/8] mtd: ubi: fix NVMEM over UBI volumes on 32-bit systems
+
+A compiler warning related to sizeof(int) != 8 when calling do_div()
+is triggered when building on 32-bit platforms.
+Address this by using integer types having a well-defined size.
+
+Fixes: 3ce485803da1 ("mtd: ubi: provide NVMEM layer over UBI volumes")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Tested-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+---
+ drivers/mtd/ubi/nvmem.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/ubi/nvmem.c
++++ b/drivers/mtd/ubi/nvmem.c
+@@ -23,9 +23,12 @@ struct ubi_nvmem {
+ static int ubi_nvmem_reg_read(void *priv, unsigned int from,
+                             void *val, size_t bytes)
+ {
+-      int err = 0, lnum = from, offs, bytes_left = bytes, to_read;
++      size_t to_read, bytes_left = bytes;
+       struct ubi_nvmem *unv = priv;
+       struct ubi_volume_desc *desc;
++      uint32_t offs;
++      uint64_t lnum = from;
++      int err = 0;
+       desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
+       if (IS_ERR(desc))
diff --git a/target/linux/generic/pending-6.6/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch b/target/linux/generic/pending-6.6/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch
deleted file mode 100644 (file)
index 063d3fa..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-From ffbbe7d66872ff8957dad2136133e28a1fd5d437 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 22:51:05 +0100
-Subject: [PATCH 01/15] dt-bindings: mtd: add basic bindings for UBI
-
-Add basic bindings for UBI devices and volumes.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../bindings/mtd/partitions/linux,ubi.yaml    | 65 +++++++++++++++++++
- .../bindings/mtd/partitions/ubi-volume.yaml   | 35 ++++++++++
- 2 files changed, 100 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
- create mode 100644 Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-@@ -0,0 +1,65 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/partitions/linux,ubi.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Unsorted Block Images
-+
-+description: |
-+  UBI ("Unsorted Block Images") is a volume management system for raw
-+  flash devices which manages multiple logical volumes on a single
-+  physical flash device and spreads the I/O load (i.e wear-leveling)
-+  across the whole flash chip.
-+
-+maintainers:
-+  - Daniel Golle <daniel@makrotopia.org>
-+
-+allOf:
-+  - $ref: partition.yaml#
-+
-+properties:
-+  compatible:
-+    const: linux,ubi
-+
-+  volumes:
-+    type: object
-+    description: UBI Volumes
-+
-+    patternProperties:
-+      "^ubi-volume-.*$":
-+        $ref: /schemas/mtd/partitions/ubi-volume.yaml#
-+
-+    unevaluatedProperties: false
-+
-+required:
-+  - compatible
-+
-+unevaluatedProperties: false
-+
-+examples:
-+  - |
-+    partitions {
-+        compatible = "fixed-partitions";
-+        #address-cells = <1>;
-+        #size-cells = <1>;
-+
-+        partition@0 {
-+            reg = <0x0 0x100000>;
-+            label = "bootloader";
-+            read-only;
-+        };
-+
-+        partition@100000 {
-+            reg = <0x100000 0x1ff00000>;
-+            label = "ubi";
-+            compatible = "linux,ubi";
-+
-+            volumes {
-+                ubi-volume-caldata {
-+                    volid = <2>;
-+                    volname = "rf";
-+                };
-+            };
-+        };
-+    };
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-@@ -0,0 +1,35 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mtd/partitions/ubi-volume.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: UBI volume
-+
-+description: |
-+  This binding describes a single UBI volume. Volumes can be matches either
-+  by their ID or their name, or both.
-+
-+maintainers:
-+  - Daniel Golle <daniel@makrotopia.org>
-+
-+properties:
-+  volid:
-+    $ref: "/schemas/types.yaml#/definitions/uint32"
-+    description:
-+      Match UBI volume ID
-+
-+  volname:
-+    $ref: "/schemas/types.yaml#/definitions/string"
-+    description:
-+      Match UBI volume ID
-+
-+anyOf:
-+  - required:
-+    - volid
-+
-+  - required:
-+    - volname
-+
-+# This is a generic file other binding inherit from and extend
-+additionalProperties: true
diff --git a/target/linux/generic/pending-6.6/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch b/target/linux/generic/pending-6.6/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch
deleted file mode 100644 (file)
index 823c8e8..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From e4dad3aa5c3ab9c553555dd23c0b85f725f2eb51 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 7 Aug 2023 22:53:01 +0100
-Subject: [PATCH 02/15] dt-bindings: mtd: ubi-volume: allow UBI volumes to
- provide NVMEM
-
-UBI volumes may be used to contain NVMEM bits, typically device MAC
-addresses or wireless radio calibration data.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- .../devicetree/bindings/mtd/partitions/linux,ubi.yaml  | 10 ++++++++++
- .../devicetree/bindings/mtd/partitions/ubi-volume.yaml |  5 +++++
- 2 files changed, 15 insertions(+)
-
---- a/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml
-@@ -59,6 +59,16 @@ examples:
-                 ubi-volume-caldata {
-                     volid = <2>;
-                     volname = "rf";
-+
-+                    nvmem-layout {
-+                        compatible = "fixed-layout";
-+                        #address-cells = <1>;
-+                        #size-cells = <1>;
-+
-+                        eeprom@0 {
-+                            reg = <0x0 0x1000>;
-+                        };
-+                    };
-                 };
-             };
-         };
---- a/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml
-@@ -24,6 +24,11 @@ properties:
-     description:
-       Match UBI volume ID
-+  nvmem-layout:
-+    $ref: /schemas/nvmem/layouts/nvmem-layout.yaml#
-+    description:
-+      This container may reference an NVMEM layout parser.
-+
- anyOf:
-   - required:
-     - volid
diff --git a/target/linux/generic/pending-6.6/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch b/target/linux/generic/pending-6.6/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch
deleted file mode 100644 (file)
index a1e1d6f..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-From e5cf19bd8204925f3bd2067df9e867313eac388b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 1 May 2023 11:57:51 +0100
-Subject: [PATCH 03/15] mtd: ubi: block: use notifier to create ubiblock from
- parameter
-
-Use UBI_VOLUME_ADDED notification to create ubiblock device specified
-on kernel cmdline or module parameter.
-This makes thing more simple and has the advantage that ubiblock devices
-on volumes which are not present at the time the ubi module is probed
-will still be created.
-
-Suggested-by: Zhihao Cheng <chengzhihao1@huawei.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 154 ++++++++++++++++++++++------------------
- 1 file changed, 85 insertions(+), 69 deletions(-)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -33,6 +33,7 @@
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/mutex.h>
-+#include <linux/namei.h>
- #include <linux/slab.h>
- #include <linux/mtd/ubi.h>
- #include <linux/blkdev.h>
-@@ -65,10 +66,10 @@ struct ubiblock_pdu {
- };
- /* Numbers of elements set in the @ubiblock_param array */
--static int ubiblock_devs __initdata;
-+static int ubiblock_devs;
- /* MTD devices specification parameters */
--static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata;
-+static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES];
- struct ubiblock {
-       struct ubi_volume_desc *desc;
-@@ -469,7 +470,7 @@ int ubiblock_remove(struct ubi_volume_in
-       }
-       /* Found a device, let's lock it so we can check if it's busy */
--      mutex_lock(&dev->dev_mutex);
-+      mutex_lock_nested(&dev->dev_mutex, SINGLE_DEPTH_NESTING);
-       if (dev->refcnt > 0) {
-               ret = -EBUSY;
-               goto out_unlock_dev;
-@@ -532,6 +533,85 @@ static int ubiblock_resize(struct ubi_vo
-       return 0;
- }
-+static bool
-+match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
-+{
-+      int err, len;
-+      struct path path;
-+      struct kstat stat;
-+
-+      if (ubi_num == -1) {
-+              /* No ubi num, name must be a vol device path */
-+              err = kern_path(name, LOOKUP_FOLLOW, &path);
-+              if (err)
-+                      return false;
-+
-+              err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT);
-+              path_put(&path);
-+              if (err)
-+                      return false;
-+
-+              if (!S_ISCHR(stat.mode))
-+                      return false;
-+
-+              if (vi->ubi_num != ubi_major2num(MAJOR(stat.rdev)))
-+                      return false;
-+
-+              if (vi->vol_id != MINOR(stat.rdev) - 1)
-+                      return false;
-+
-+              return true;
-+      }
-+
-+      if (vol_id == -1) {
-+              if (vi->ubi_num != ubi_num)
-+                      return false;
-+
-+              len = strnlen(name, UBI_VOL_NAME_MAX + 1);
-+              if (len < 1 || vi->name_len != len)
-+                      return false;
-+
-+              if (strcmp(name, vi->name))
-+                      return false;
-+
-+              return true;
-+      }
-+
-+      if (vi->ubi_num != ubi_num)
-+              return false;
-+
-+      if (vi->vol_id != vol_id)
-+              return false;
-+
-+      return true;
-+}
-+
-+static void
-+ubiblock_create_from_param(struct ubi_volume_info *vi)
-+{
-+      int i, ret = 0;
-+      struct ubiblock_param *p;
-+
-+      /*
-+       * Iterate over ubiblock cmdline parameters. If a parameter matches the
-+       * newly added volume create the ubiblock device for it.
-+       */
-+      for (i = 0; i < ubiblock_devs; i++) {
-+              p = &ubiblock_param[i];
-+
-+              if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
-+                      continue;
-+
-+              ret = ubiblock_create(vi);
-+              if (ret) {
-+                      pr_err(
-+                             "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
-+                             vi->name, p->ubi_num, p->vol_id, ret);
-+              }
-+              break;
-+      }
-+}
-+
- static int ubiblock_notify(struct notifier_block *nb,
-                        unsigned long notification_type, void *ns_ptr)
- {
-@@ -539,10 +619,7 @@ static int ubiblock_notify(struct notifi
-       switch (notification_type) {
-       case UBI_VOLUME_ADDED:
--              /*
--               * We want to enforce explicit block device creation for
--               * volumes, so when a volume is added we do nothing.
--               */
-+              ubiblock_create_from_param(&nt->vi);
-               break;
-       case UBI_VOLUME_REMOVED:
-               ubiblock_remove(&nt->vi);
-@@ -568,56 +645,6 @@ static struct notifier_block ubiblock_no
-       .notifier_call = ubiblock_notify,
- };
--static struct ubi_volume_desc * __init
--open_volume_desc(const char *name, int ubi_num, int vol_id)
--{
--      if (ubi_num == -1)
--              /* No ubi num, name must be a vol device path */
--              return ubi_open_volume_path(name, UBI_READONLY);
--      else if (vol_id == -1)
--              /* No vol_id, must be vol_name */
--              return ubi_open_volume_nm(ubi_num, name, UBI_READONLY);
--      else
--              return ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
--}
--
--static void __init ubiblock_create_from_param(void)
--{
--      int i, ret = 0;
--      struct ubiblock_param *p;
--      struct ubi_volume_desc *desc;
--      struct ubi_volume_info vi;
--
--      /*
--       * If there is an error creating one of the ubiblocks, continue on to
--       * create the following ubiblocks. This helps in a circumstance where
--       * the kernel command-line specifies multiple block devices and some
--       * may be broken, but we still want the working ones to come up.
--       */
--      for (i = 0; i < ubiblock_devs; i++) {
--              p = &ubiblock_param[i];
--
--              desc = open_volume_desc(p->name, p->ubi_num, p->vol_id);
--              if (IS_ERR(desc)) {
--                      pr_err(
--                             "UBI: block: can't open volume on ubi%d_%d, err=%ld\n",
--                             p->ubi_num, p->vol_id, PTR_ERR(desc));
--                      continue;
--              }
--
--              ubi_get_volume_info(desc, &vi);
--              ubi_close_volume(desc);
--
--              ret = ubiblock_create(&vi);
--              if (ret) {
--                      pr_err(
--                             "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n",
--                             vi.name, p->ubi_num, p->vol_id, ret);
--                      continue;
--              }
--      }
--}
--
- static void ubiblock_remove_all(void)
- {
-       struct ubiblock *next;
-@@ -643,18 +670,7 @@ int __init ubiblock_init(void)
-       if (ubiblock_major < 0)
-               return ubiblock_major;
--      /*
--       * Attach block devices from 'block=' module param.
--       * Even if one block device in the param list fails to come up,
--       * still allow the module to load and leave any others up.
--       */
--      ubiblock_create_from_param();
--
--      /*
--       * Block devices are only created upon user requests, so we ignore
--       * existing volumes.
--       */
--      ret = ubi_register_volume_notifier(&ubiblock_notifier, 1);
-+      ret = ubi_register_volume_notifier(&ubiblock_notifier, 0);
-       if (ret)
-               goto err_unreg;
-       return 0;
diff --git a/target/linux/generic/pending-6.6/450-04-mtd-ubi-attach-from-device-tree.patch b/target/linux/generic/pending-6.6/450-04-mtd-ubi-attach-from-device-tree.patch
deleted file mode 100644 (file)
index a295146..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-From 471a17d8d1b838092d1a76e48cdce8b5b67ff809 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 27 Nov 2023 01:54:28 +0000
-Subject: [PATCH 04/15] mtd: ubi: attach from device tree
-
-Introduce device tree compatible 'linux,ubi' and attach compatible MTD
-devices using the MTD add notifier. This is needed for a UBI device to
-be available early at boot (and not only after late_initcall), so
-volumes on them can be used eg. as NVMEM providers for other drivers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/build.c | 146 ++++++++++++++++++++++++++++------------
- drivers/mtd/ubi/cdev.c  |   2 +-
- drivers/mtd/ubi/ubi.h   |   2 +-
- 3 files changed, 106 insertions(+), 44 deletions(-)
-
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -27,6 +27,7 @@
- #include <linux/log2.h>
- #include <linux/kthread.h>
- #include <linux/kernel.h>
-+#include <linux/of.h>
- #include <linux/slab.h>
- #include <linux/major.h>
- #include "ubi.h"
-@@ -1072,6 +1073,7 @@ out_free:
-  * ubi_detach_mtd_dev - detach an MTD device.
-  * @ubi_num: UBI device number to detach from
-  * @anyway: detach MTD even if device reference count is not zero
-+ * @have_lock: called by MTD notifier holding mtd_table_mutex
-  *
-  * This function destroys an UBI device number @ubi_num and detaches the
-  * underlying MTD device. Returns zero in case of success and %-EBUSY if the
-@@ -1081,7 +1083,7 @@ out_free:
-  * Note, the invocations of this function has to be serialized by the
-  * @ubi_devices_mutex.
-  */
--int ubi_detach_mtd_dev(int ubi_num, int anyway)
-+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock)
- {
-       struct ubi_device *ubi;
-@@ -1137,7 +1139,11 @@ int ubi_detach_mtd_dev(int ubi_num, int
-       vfree(ubi->peb_buf);
-       vfree(ubi->fm_buf);
-       ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index);
--      put_mtd_device(ubi->mtd);
-+      if (have_lock)
-+              __put_mtd_device(ubi->mtd);
-+      else
-+              put_mtd_device(ubi->mtd);
-+
-       put_device(&ubi->dev);
-       return 0;
- }
-@@ -1214,43 +1220,43 @@ static struct mtd_info * __init open_mtd
-       return mtd;
- }
--static int __init ubi_init(void)
-+static void ubi_notify_add(struct mtd_info *mtd)
- {
--      int err, i, k;
-+      struct device_node *np = mtd_get_of_node(mtd);
-+      int err;
--      /* Ensure that EC and VID headers have correct size */
--      BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
--      BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
-+      if (!of_device_is_compatible(np, "linux,ubi"))
-+              return;
--      if (mtd_devs > UBI_MAX_DEVICES) {
--              pr_err("UBI error: too many MTD devices, maximum is %d\n",
--                     UBI_MAX_DEVICES);
--              return -EINVAL;
--      }
-+      /*
-+       * we are already holding &mtd_table_mutex, but still need
-+       * to bump refcount
-+       */
-+      err = __get_mtd_device(mtd);
-+      if (err)
-+              return;
--      /* Create base sysfs directory and sysfs files */
--      err = class_register(&ubi_class);
-+      /* called while holding mtd_table_mutex */
-+      mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING);
-+      err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false);
-+      mutex_unlock(&ubi_devices_mutex);
-       if (err < 0)
--              return err;
--
--      err = misc_register(&ubi_ctrl_cdev);
--      if (err) {
--              pr_err("UBI error: cannot register device\n");
--              goto out;
--      }
-+              __put_mtd_device(mtd);
-+}
--      ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
--                                            sizeof(struct ubi_wl_entry),
--                                            0, 0, NULL);
--      if (!ubi_wl_entry_slab) {
--              err = -ENOMEM;
--              goto out_dev_unreg;
--      }
-+static void ubi_notify_remove(struct mtd_info *mtd)
-+{
-+      WARN(1, "mtd%d removed despite UBI still being attached", mtd->index);
-+}
--      err = ubi_debugfs_init();
--      if (err)
--              goto out_slab;
-+static struct mtd_notifier ubi_mtd_notifier = {
-+      .add = ubi_notify_add,
-+      .remove = ubi_notify_remove,
-+};
-+static int __init ubi_init_attach(void)
-+{
-+      int err, i, k;
-       /* Attach MTD devices */
-       for (i = 0; i < mtd_devs; i++) {
-@@ -1298,25 +1304,79 @@ static int __init ubi_init(void)
-               }
-       }
-+      return 0;
-+
-+out_detach:
-+      for (k = 0; k < i; k++)
-+              if (ubi_devices[k]) {
-+                      mutex_lock(&ubi_devices_mutex);
-+                      ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1, false);
-+                      mutex_unlock(&ubi_devices_mutex);
-+              }
-+      return err;
-+}
-+#ifndef CONFIG_MTD_UBI_MODULE
-+late_initcall(ubi_init_attach);
-+#endif
-+
-+static int __init ubi_init(void)
-+{
-+      int err;
-+
-+      /* Ensure that EC and VID headers have correct size */
-+      BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64);
-+      BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64);
-+
-+      if (mtd_devs > UBI_MAX_DEVICES) {
-+              pr_err("UBI error: too many MTD devices, maximum is %d\n",
-+                     UBI_MAX_DEVICES);
-+              return -EINVAL;
-+      }
-+
-+      /* Create base sysfs directory and sysfs files */
-+      err = class_register(&ubi_class);
-+      if (err < 0)
-+              return err;
-+
-+      err = misc_register(&ubi_ctrl_cdev);
-+      if (err) {
-+              pr_err("UBI error: cannot register device\n");
-+              goto out;
-+      }
-+
-+      ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab",
-+                                            sizeof(struct ubi_wl_entry),
-+                                            0, 0, NULL);
-+      if (!ubi_wl_entry_slab) {
-+              err = -ENOMEM;
-+              goto out_dev_unreg;
-+      }
-+
-+      err = ubi_debugfs_init();
-+      if (err)
-+              goto out_slab;
-+
-       err = ubiblock_init();
-       if (err) {
-               pr_err("UBI error: block: cannot initialize, error %d\n", err);
-               /* See comment above re-ubi_is_module(). */
-               if (ubi_is_module())
--                      goto out_detach;
-+                      goto out_slab;
-+      }
-+
-+      register_mtd_user(&ubi_mtd_notifier);
-+
-+      if (ubi_is_module()) {
-+              err = ubi_init_attach();
-+              if (err)
-+                      goto out_mtd_notifier;
-       }
-       return 0;
--out_detach:
--      for (k = 0; k < i; k++)
--              if (ubi_devices[k]) {
--                      mutex_lock(&ubi_devices_mutex);
--                      ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1);
--                      mutex_unlock(&ubi_devices_mutex);
--              }
--      ubi_debugfs_exit();
-+out_mtd_notifier:
-+      unregister_mtd_user(&ubi_mtd_notifier);
- out_slab:
-       kmem_cache_destroy(ubi_wl_entry_slab);
- out_dev_unreg:
-@@ -1326,18 +1386,20 @@ out:
-       pr_err("UBI error: cannot initialize UBI, error %d\n", err);
-       return err;
- }
--late_initcall(ubi_init);
-+device_initcall(ubi_init);
-+
- static void __exit ubi_exit(void)
- {
-       int i;
-       ubiblock_exit();
-+      unregister_mtd_user(&ubi_mtd_notifier);
-       for (i = 0; i < UBI_MAX_DEVICES; i++)
-               if (ubi_devices[i]) {
-                       mutex_lock(&ubi_devices_mutex);
--                      ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1);
-+                      ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1, false);
-                       mutex_unlock(&ubi_devices_mutex);
-               }
-       ubi_debugfs_exit();
---- a/drivers/mtd/ubi/cdev.c
-+++ b/drivers/mtd/ubi/cdev.c
-@@ -1065,7 +1065,7 @@ static long ctrl_cdev_ioctl(struct file
-               }
-               mutex_lock(&ubi_devices_mutex);
--              err = ubi_detach_mtd_dev(ubi_num, 0);
-+              err = ubi_detach_mtd_dev(ubi_num, 0, false);
-               mutex_unlock(&ubi_devices_mutex);
-               break;
-       }
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -939,7 +939,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi
- int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
-                      int vid_hdr_offset, int max_beb_per1024,
-                      bool disable_fm);
--int ubi_detach_mtd_dev(int ubi_num, int anyway);
-+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock);
- struct ubi_device *ubi_get_device(int ubi_num);
- void ubi_put_device(struct ubi_device *ubi);
- struct ubi_device *ubi_get_by_major(int major);
diff --git a/target/linux/generic/pending-6.6/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch b/target/linux/generic/pending-6.6/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch
deleted file mode 100644 (file)
index c7c058f..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-From 2d664266cfdd114cc7a1fa28dd64275e99222455 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 8 Jun 2023 17:18:09 +0100
-Subject: [PATCH 05/15] mtd: ubi: introduce pre-removal notification for UBI
- volumes
-
-Introduce a new notification type UBI_VOLUME_SHUTDOWN to inform users
-that a volume is just about to be removed.
-This is needed because users (such as the NVMEM subsystem) expect that
-at the time their removal function is called, the parenting device is
-still available (for removal of sysfs nodes, for example, in case of
-NVMEM which otherwise WARNs on volume removal).
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/block.c | 26 ++++++++++++++++++++++++++
- drivers/mtd/ubi/build.c | 20 +++++++++++++++-----
- drivers/mtd/ubi/kapi.c  |  2 +-
- drivers/mtd/ubi/ubi.h   |  2 ++
- drivers/mtd/ubi/vmt.c   | 17 +++++++++++++++--
- include/linux/mtd/ubi.h |  2 ++
- 6 files changed, 61 insertions(+), 8 deletions(-)
-
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -533,6 +533,29 @@ static int ubiblock_resize(struct ubi_vo
-       return 0;
- }
-+static int ubiblock_shutdown(struct ubi_volume_info *vi)
-+{
-+      struct ubiblock *dev;
-+      struct gendisk *disk;
-+      int ret = 0;
-+
-+      mutex_lock(&devices_mutex);
-+      dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
-+      if (!dev) {
-+              ret = -ENODEV;
-+              goto out_unlock;
-+      }
-+      disk = dev->gd;
-+
-+out_unlock:
-+      mutex_unlock(&devices_mutex);
-+
-+      if (!ret)
-+              blk_mark_disk_dead(disk);
-+
-+      return ret;
-+};
-+
- static bool
- match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id)
- {
-@@ -624,6 +647,9 @@ static int ubiblock_notify(struct notifi
-       case UBI_VOLUME_REMOVED:
-               ubiblock_remove(&nt->vi);
-               break;
-+      case UBI_VOLUME_SHUTDOWN:
-+              ubiblock_shutdown(&nt->vi);
-+              break;
-       case UBI_VOLUME_RESIZED:
-               ubiblock_resize(&nt->vi);
-               break;
---- a/drivers/mtd/ubi/build.c
-+++ b/drivers/mtd/ubi/build.c
-@@ -91,7 +91,7 @@ static struct ubi_device *ubi_devices[UB
- /* Serializes UBI devices creations and removals */
- DEFINE_MUTEX(ubi_devices_mutex);
--/* Protects @ubi_devices and @ubi->ref_count */
-+/* Protects @ubi_devices, @ubi->ref_count and @ubi->is_dead */
- static DEFINE_SPINLOCK(ubi_devices_lock);
- /* "Show" method for files in '/<sysfs>/class/ubi/' */
-@@ -259,6 +259,9 @@ struct ubi_device *ubi_get_device(int ub
-       spin_lock(&ubi_devices_lock);
-       ubi = ubi_devices[ubi_num];
-+      if (ubi && ubi->is_dead)
-+              ubi = NULL;
-+
-       if (ubi) {
-               ubi_assert(ubi->ref_count >= 0);
-               ubi->ref_count += 1;
-@@ -296,7 +299,7 @@ struct ubi_device *ubi_get_by_major(int
-       spin_lock(&ubi_devices_lock);
-       for (i = 0; i < UBI_MAX_DEVICES; i++) {
-               ubi = ubi_devices[i];
--              if (ubi && MAJOR(ubi->cdev.dev) == major) {
-+              if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
-                       ubi_assert(ubi->ref_count >= 0);
-                       ubi->ref_count += 1;
-                       get_device(&ubi->dev);
-@@ -325,7 +328,7 @@ int ubi_major2num(int major)
-       for (i = 0; i < UBI_MAX_DEVICES; i++) {
-               struct ubi_device *ubi = ubi_devices[i];
--              if (ubi && MAJOR(ubi->cdev.dev) == major) {
-+              if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) {
-                       ubi_num = ubi->ubi_num;
-                       break;
-               }
-@@ -512,7 +515,7 @@ static void ubi_free_volumes_from(struct
-       int i;
-       for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
--              if (!ubi->volumes[i])
-+              if (!ubi->volumes[i] || ubi->volumes[i]->is_dead)
-                       continue;
-               ubi_eba_replace_table(ubi->volumes[i], NULL);
-               ubi_fastmap_destroy_checkmap(ubi->volumes[i]);
-@@ -1095,10 +1098,10 @@ int ubi_detach_mtd_dev(int ubi_num, int
-               return -EINVAL;
-       spin_lock(&ubi_devices_lock);
--      put_device(&ubi->dev);
-       ubi->ref_count -= 1;
-       if (ubi->ref_count) {
-               if (!anyway) {
-+                      ubi->ref_count += 1;
-                       spin_unlock(&ubi_devices_lock);
-                       return -EBUSY;
-               }
-@@ -1106,6 +1109,13 @@ int ubi_detach_mtd_dev(int ubi_num, int
-               ubi_err(ubi, "%s reference count %d, destroy anyway",
-                       ubi->ubi_name, ubi->ref_count);
-       }
-+      ubi->is_dead = true;
-+      spin_unlock(&ubi_devices_lock);
-+
-+      ubi_notify_all(ubi, UBI_VOLUME_SHUTDOWN, NULL);
-+
-+      spin_lock(&ubi_devices_lock);
-+      put_device(&ubi->dev);
-       ubi_devices[ubi_num] = NULL;
-       spin_unlock(&ubi_devices_lock);
---- a/drivers/mtd/ubi/kapi.c
-+++ b/drivers/mtd/ubi/kapi.c
-@@ -152,7 +152,7 @@ struct ubi_volume_desc *ubi_open_volume(
-       spin_lock(&ubi->volumes_lock);
-       vol = ubi->volumes[vol_id];
--      if (!vol)
-+      if (!vol || vol->is_dead)
-               goto out_unlock;
-       err = -EBUSY;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -345,6 +345,7 @@ struct ubi_volume {
-       int writers;
-       int exclusive;
-       int metaonly;
-+      bool is_dead;
-       int reserved_pebs;
-       int vol_type;
-@@ -564,6 +565,7 @@ struct ubi_device {
-       spinlock_t volumes_lock;
-       int ref_count;
-       int image_seq;
-+      bool is_dead;
-       int rsvd_pebs;
-       int avail_pebs;
---- a/drivers/mtd/ubi/vmt.c
-+++ b/drivers/mtd/ubi/vmt.c
-@@ -59,7 +59,7 @@ static ssize_t vol_attribute_show(struct
-       struct ubi_device *ubi = vol->ubi;
-       spin_lock(&ubi->volumes_lock);
--      if (!ubi->volumes[vol->vol_id]) {
-+      if (!ubi->volumes[vol->vol_id] || ubi->volumes[vol->vol_id]->is_dead) {
-               spin_unlock(&ubi->volumes_lock);
-               return -ENODEV;
-       }
-@@ -189,7 +189,7 @@ int ubi_create_volume(struct ubi_device
-       /* Ensure that the name is unique */
-       for (i = 0; i < ubi->vtbl_slots; i++)
--              if (ubi->volumes[i] &&
-+              if (ubi->volumes[i] && !ubi->volumes[i]->is_dead &&
-                   ubi->volumes[i]->name_len == req->name_len &&
-                   !strcmp(ubi->volumes[i]->name, req->name)) {
-                       ubi_err(ubi, "volume \"%s\" exists (ID %d)",
-@@ -352,6 +352,19 @@ int ubi_remove_volume(struct ubi_volume_
-               err = -EBUSY;
-               goto out_unlock;
-       }
-+
-+      /*
-+       * Mark volume as dead at this point to prevent that anyone
-+       * can take a reference to the volume from now on.
-+       * This is necessary as we have to release the spinlock before
-+       * calling ubi_volume_notify.
-+       */
-+      vol->is_dead = true;
-+      spin_unlock(&ubi->volumes_lock);
-+
-+      ubi_volume_notify(ubi, vol, UBI_VOLUME_SHUTDOWN);
-+
-+      spin_lock(&ubi->volumes_lock);
-       ubi->volumes[vol_id] = NULL;
-       spin_unlock(&ubi->volumes_lock);
---- a/include/linux/mtd/ubi.h
-+++ b/include/linux/mtd/ubi.h
-@@ -192,6 +192,7 @@ struct ubi_device_info {
-  *                    or a volume was removed)
-  * @UBI_VOLUME_RESIZED: a volume has been re-sized
-  * @UBI_VOLUME_RENAMED: a volume has been re-named
-+ * @UBI_VOLUME_SHUTDOWN: a volume is going to removed, shutdown users
-  * @UBI_VOLUME_UPDATED: data has been written to a volume
-  *
-  * These constants define which type of event has happened when a volume
-@@ -202,6 +203,7 @@ enum {
-       UBI_VOLUME_REMOVED,
-       UBI_VOLUME_RESIZED,
-       UBI_VOLUME_RENAMED,
-+      UBI_VOLUME_SHUTDOWN,
-       UBI_VOLUME_UPDATED,
- };
diff --git a/target/linux/generic/pending-6.6/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch b/target/linux/generic/pending-6.6/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch
deleted file mode 100644 (file)
index 1322766..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From 3a041ee543cdf2e707a1dd72946cd6a583509b28 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 21 Jul 2023 19:26:37 +0100
-Subject: [PATCH 06/15] mtd: ubi: populate ubi volume fwnode
-
-Look for the 'volumes' subnode of an MTD partition attached to a UBI
-device and attach matching child nodes to UBI volumes.
-This allows UBI volumes to be referenced in device tree, e.g. for use
-as NVMEM providers.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/vmt.c | 27 +++++++++++++++++++++++++++
- 1 file changed, 27 insertions(+)
-
---- a/drivers/mtd/ubi/vmt.c
-+++ b/drivers/mtd/ubi/vmt.c
-@@ -124,6 +124,31 @@ static void vol_release(struct device *d
-       kfree(vol);
- }
-+static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol)
-+{
-+      struct fwnode_handle *fw_vols, *fw_vol;
-+      const char *volname;
-+      u32 volid;
-+
-+      fw_vols = device_get_named_child_node(vol->dev.parent->parent, "volumes");
-+      if (!fw_vols)
-+              return NULL;
-+
-+      fwnode_for_each_child_node(fw_vols, fw_vol) {
-+              if (!fwnode_property_read_string(fw_vol, "volname", &volname) &&
-+                  strncmp(volname, vol->name, vol->name_len))
-+                      continue;
-+
-+              if (!fwnode_property_read_u32(fw_vol, "volid", &volid) &&
-+                  vol->vol_id != volid)
-+                      continue;
-+
-+              return fw_vol;
-+      }
-+
-+      return NULL;
-+}
-+
- /**
-  * ubi_create_volume - create volume.
-  * @ubi: UBI device description object
-@@ -223,6 +248,7 @@ int ubi_create_volume(struct ubi_device
-       vol->name_len  = req->name_len;
-       memcpy(vol->name, req->name, vol->name_len);
-       vol->ubi = ubi;
-+      device_set_node(&vol->dev, find_volume_fwnode(vol));
-       /*
-        * Finish all pending erases because there may be some LEBs belonging
-@@ -605,6 +631,7 @@ int ubi_add_volume(struct ubi_device *ub
-       vol->dev.class = &ubi_class;
-       vol->dev.groups = volume_dev_groups;
-       dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
-+      device_set_node(&vol->dev, find_volume_fwnode(vol));
-       err = device_register(&vol->dev);
-       if (err) {
-               cdev_del(&vol->cdev);
diff --git a/target/linux/generic/pending-6.6/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch b/target/linux/generic/pending-6.6/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch
deleted file mode 100644 (file)
index 59a1eb9..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-From 7eb6666348f3f2d1f7308c712fa5903cbe189401 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 8 Jun 2023 17:22:04 +0100
-Subject: [PATCH 07/15] mtd: ubi: provide NVMEM layer over UBI volumes
-
-In an ideal world we would like UBI to be used where ever possible on a
-NAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it
-is possible to achieve an (almost-)all-UBI flash layout. Hence the need
-for a way to also use UBI volumes to store board-level constants, such
-as MAC addresses and calibration data of wireless interfaces.
-
-Add UBI volume NVMEM driver module exposing UBI volumes as NVMEM
-providers. Allow UBI devices to have a "volumes" firmware subnode with
-volumes which may be compatible with "nvmem-cells".
-Access to UBI volumes via the NVMEM interface at this point is
-read-only, and it is slow, opening and closing the UBI volume for each
-access due to limitations of the NVMEM provider API.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/mtd/ubi/Kconfig  |  12 +++
- drivers/mtd/ubi/Makefile |   1 +
- drivers/mtd/ubi/nvmem.c  | 188 +++++++++++++++++++++++++++++++++++++++
- 3 files changed, 201 insertions(+)
- create mode 100644 drivers/mtd/ubi/nvmem.c
-
---- a/drivers/mtd/ubi/Kconfig
-+++ b/drivers/mtd/ubi/Kconfig
-@@ -104,4 +104,16 @@ config MTD_UBI_BLOCK
-          If in doubt, say "N".
-+config MTD_UBI_NVMEM
-+      tristate "UBI virtual NVMEM"
-+      default n
-+      depends on NVMEM
-+      help
-+         This option enabled an additional driver exposing UBI volumes as NVMEM
-+         providers, intended for platforms where UBI is part of the firmware
-+         specification and used to store also e.g. MAC addresses or board-
-+         specific Wi-Fi calibration data.
-+
-+         If in doubt, say "N".
-+
- endif # MTD_UBI
---- a/drivers/mtd/ubi/Makefile
-+++ b/drivers/mtd/ubi/Makefile
-@@ -7,3 +7,4 @@ ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap
- ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o
- obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
-+obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o
---- /dev/null
-+++ b/drivers/mtd/ubi/nvmem.c
-@@ -0,0 +1,191 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+/* UBI NVMEM provider */
-+#include "ubi.h"
-+#include <linux/nvmem-provider.h>
-+#include <asm/div64.h>
-+
-+/* List of all NVMEM devices */
-+static LIST_HEAD(nvmem_devices);
-+static DEFINE_MUTEX(devices_mutex);
-+
-+struct ubi_nvmem {
-+      struct nvmem_device *nvmem;
-+      int ubi_num;
-+      int vol_id;
-+      int usable_leb_size;
-+      struct list_head list;
-+};
-+
-+static int ubi_nvmem_reg_read(void *priv, unsigned int from,
-+                            void *val, size_t bytes)
-+{
-+      uint32_t offs, to_read, bytes_left;
-+      struct ubi_nvmem *unv = priv;
-+      struct ubi_volume_desc *desc;
-+      uint64_t lnum = from;
-+      int err = 0;
-+
-+      desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);
-+      if (IS_ERR(desc))
-+              return PTR_ERR(desc);
-+
-+      bytes_left = bytes;
-+      offs = do_div(lnum, unv->usable_leb_size);
-+      while (bytes_left) {
-+              to_read = unv->usable_leb_size - offs;
-+
-+              if (to_read > bytes_left)
-+                      to_read = bytes_left;
-+
-+              err = ubi_read(desc, lnum, val, offs, to_read);
-+              if (err)
-+                      break;
-+
-+              lnum += 1;
-+              offs = 0;
-+              bytes_left -= to_read;
-+              val += to_read;
-+      }
-+      ubi_close_volume(desc);
-+
-+      if (err)
-+              return err;
-+
-+      return bytes_left == 0 ? 0 : -EIO;
-+}
-+
-+static int ubi_nvmem_add(struct ubi_volume_info *vi)
-+{
-+      struct device_node *np = dev_of_node(vi->dev);
-+      struct nvmem_config config = {};
-+      struct ubi_nvmem *unv;
-+      int ret;
-+
-+      if (!np)
-+              return 0;
-+
-+      if (!of_get_child_by_name(np, "nvmem-layout"))
-+              return 0;
-+
-+      if (WARN_ON_ONCE(vi->usable_leb_size <= 0) ||
-+          WARN_ON_ONCE(vi->size <= 0))
-+              return -EINVAL;
-+
-+      unv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL);
-+      if (!unv)
-+              return -ENOMEM;
-+
-+      config.id = NVMEM_DEVID_NONE;
-+      config.dev = vi->dev;
-+      config.name = dev_name(vi->dev);
-+      config.owner = THIS_MODULE;
-+      config.priv = unv;
-+      config.reg_read = ubi_nvmem_reg_read;
-+      config.size = vi->usable_leb_size * vi->size;
-+      config.word_size = 1;
-+      config.stride = 1;
-+      config.read_only = true;
-+      config.root_only = true;
-+      config.ignore_wp = true;
-+      config.of_node = np;
-+
-+      unv->ubi_num = vi->ubi_num;
-+      unv->vol_id = vi->vol_id;
-+      unv->usable_leb_size = vi->usable_leb_size;
-+      unv->nvmem = nvmem_register(&config);
-+      if (IS_ERR(unv->nvmem)) {
-+              ret = dev_err_probe(vi->dev, PTR_ERR(unv->nvmem),
-+                                  "Failed to register NVMEM device\n");
-+              kfree(unv);
-+              return ret;
-+      }
-+
-+      mutex_lock(&devices_mutex);
-+      list_add_tail(&unv->list, &nvmem_devices);
-+      mutex_unlock(&devices_mutex);
-+
-+      return 0;
-+}
-+
-+static void ubi_nvmem_remove(struct ubi_volume_info *vi)
-+{
-+      struct ubi_nvmem *unv_c, *unv = NULL;
-+
-+      mutex_lock(&devices_mutex);
-+      list_for_each_entry(unv_c, &nvmem_devices, list)
-+              if (unv_c->ubi_num == vi->ubi_num && unv_c->vol_id == vi->vol_id) {
-+                      unv = unv_c;
-+                      break;
-+              }
-+
-+      if (!unv) {
-+              mutex_unlock(&devices_mutex);
-+              return;
-+      }
-+
-+      list_del(&unv->list);
-+      mutex_unlock(&devices_mutex);
-+      nvmem_unregister(unv->nvmem);
-+      kfree(unv);
-+}
-+
-+/**
-+ * nvmem_notify - UBI notification handler.
-+ * @nb: registered notifier block
-+ * @l: notification type
-+ * @ns_ptr: pointer to the &struct ubi_notification object
-+ */
-+static int nvmem_notify(struct notifier_block *nb, unsigned long l,
-+                       void *ns_ptr)
-+{
-+      struct ubi_notification *nt = ns_ptr;
-+
-+      switch (l) {
-+      case UBI_VOLUME_RESIZED:
-+              ubi_nvmem_remove(&nt->vi);
-+              fallthrough;
-+      case UBI_VOLUME_ADDED:
-+              ubi_nvmem_add(&nt->vi);
-+              break;
-+      case UBI_VOLUME_SHUTDOWN:
-+              ubi_nvmem_remove(&nt->vi);
-+              break;
-+      default:
-+              break;
-+      }
-+      return NOTIFY_OK;
-+}
-+
-+static struct notifier_block nvmem_notifier = {
-+      .notifier_call = nvmem_notify,
-+};
-+
-+static int __init ubi_nvmem_init(void)
-+{
-+      return ubi_register_volume_notifier(&nvmem_notifier, 0);
-+}
-+
-+static void __exit ubi_nvmem_exit(void)
-+{
-+      struct ubi_nvmem *unv, *tmp;
-+
-+      mutex_lock(&devices_mutex);
-+      list_for_each_entry_safe(unv, tmp, &nvmem_devices, list) {
-+              nvmem_unregister(unv->nvmem);
-+              list_del(&unv->list);
-+              kfree(unv);
-+      }
-+      mutex_unlock(&devices_mutex);
-+
-+      ubi_unregister_volume_notifier(&nvmem_notifier);
-+}
-+
-+module_init(ubi_nvmem_init);
-+module_exit(ubi_nvmem_exit);
-+MODULE_DESCRIPTION("NVMEM layer over UBI volumes");
-+MODULE_AUTHOR("Daniel Golle");
-+MODULE_LICENSE("GPL");
index 5a897d5d6f5506d9e103510ff89f7f9dd5af3022..6405865c459e7ec51a36788df11615dfc611db53 100644 (file)
@@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/drivers/mtd/ubi/build.c
 +++ b/drivers/mtd/ubi/build.c
-@@ -1264,6 +1264,74 @@ static struct mtd_notifier ubi_mtd_notif
+@@ -1258,6 +1258,74 @@ static struct mtd_notifier ubi_mtd_notif
        .remove = ubi_notify_remove,
  };
  
@@ -83,7 +83,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static int __init ubi_init_attach(void)
  {
        int err, i, k;
-@@ -1314,6 +1382,12 @@ static int __init ubi_init_attach(void)
+@@ -1308,6 +1376,12 @@ static int __init ubi_init_attach(void)
                }
        }
  
index e0134e876a33dbfa03cd66acdd3dbfd13da10b0d..6081d1d9e5d6f89bd8a52c54242cce8a7ba37827 100644 (file)
@@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/drivers/mtd/ubi/block.c
 +++ b/drivers/mtd/ubi/block.c
-@@ -609,10 +609,47 @@ match_volume_desc(struct ubi_volume_info
+@@ -570,10 +570,47 @@ match_volume_desc(struct ubi_volume_info
        return true;
  }
  
@@ -56,7 +56,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
        struct ubiblock_param *p;
  
        /*
-@@ -625,6 +662,7 @@ ubiblock_create_from_param(struct ubi_vo
+@@ -586,6 +623,7 @@ ubiblock_create_from_param(struct ubi_vo
                if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id))
                        continue;
  
@@ -64,7 +64,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                ret = ubiblock_create(vi);
                if (ret) {
                        pr_err(
-@@ -633,6 +671,10 @@ ubiblock_create_from_param(struct ubi_vo
+@@ -594,6 +632,10 @@ ubiblock_create_from_param(struct ubi_vo
                }
                break;
        }
index 788690088a3fff4b2127824cf02a792a57751395..367bf6598e2a997052420fbd83c6e6a7228e6ec9 100644 (file)
@@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/drivers/mtd/ubi/block.c
 +++ b/drivers/mtd/ubi/block.c
-@@ -42,6 +42,7 @@
+@@ -41,6 +41,7 @@
  #include <linux/scatterlist.h>
  #include <linux/idr.h>
  #include <asm/div64.h>
@@ -16,7 +16,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  
  #include "ubi-media.h"
  #include "ubi.h"
-@@ -429,6 +430,15 @@ int ubiblock_create(struct ubi_volume_in
+@@ -428,6 +429,15 @@ int ubiblock_create(struct ubi_volume_in
        dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
                 dev->ubi_num, dev->vol_id, vi->name);
        mutex_unlock(&devices_mutex);
index 2d85313f8d59ba5a2ab19cc28bf62b438437e41e..185ec105d0a266ff132f271f390d1c454eee20f4 100644 (file)
@@ -193,7 +193,7 @@ Subject: [PATCH] kernel: add block fit partition parser
        set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
 --- a/drivers/mtd/ubi/block.c
 +++ b/drivers/mtd/ubi/block.c
-@@ -411,7 +411,9 @@ int ubiblock_create(struct ubi_volume_in
+@@ -410,7 +410,9 @@ int ubiblock_create(struct ubi_volume_in
                ret = -ENODEV;
                goto out_cleanup_disk;
        }