treewide: remove files for building 5.10 kernel
[openwrt/openwrt.git] / target / linux / generic / backport-5.10 / 411-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch
diff --git a/target/linux/generic/backport-5.10/411-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch b/target/linux/generic/backport-5.10/411-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch
deleted file mode 100644 (file)
index 5ed6fd1..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-From 9b78ef0c7997052e9eaa0f7a4513d546fa17358c Mon Sep 17 00:00:00 2001
-From: Mikhail Zhilkin <csharper2005@gmail.com>
-Date: Sun, 29 May 2022 11:07:14 +0000
-Subject: [PATCH] mtd: parsers: add support for Sercomm partitions
-
-This adds an MTD partition parser for the Sercomm partition table that
-is used in some Beeline, Netgear and Sercomm routers.
-
-The Sercomm partition map table contains real partition offsets, which
-may differ from device to device depending on the number and location of
-bad blocks on NAND.
-
-Original patch (proposed by NOGUCHI Hiroshi):
-Link: https://github.com/openwrt/openwrt/pull/1318#issuecomment-420607394
-
-Signed-off-by: NOGUCHI Hiroshi <drvlabo@gmail.com>
-Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20220529110714.189732-1-csharper2005@gmail.com
----
- drivers/mtd/parsers/Kconfig  |   9 ++
- drivers/mtd/parsers/Makefile |   1 +
- drivers/mtd/parsers/scpart.c | 248 +++++++++++++++++++++++++++++++++++
- 3 files changed, 258 insertions(+)
- create mode 100644 drivers/mtd/parsers/scpart.c
-
---- a/drivers/mtd/parsers/Kconfig
-+++ b/drivers/mtd/parsers/Kconfig
-@@ -179,3 +179,12 @@ config MTD_REDBOOT_PARTS_READONLY
-         'FIS directory' images, enable this option.
- endif # MTD_REDBOOT_PARTS
-+
-+config MTD_SERCOMM_PARTS
-+      tristate "Sercomm partition table parser"
-+      depends on MTD && RALINK
-+      help
-+        This provides partitions table parser for devices with Sercomm
-+        partition map. This partition table contains real partition
-+        offsets, which may differ from device to device depending on the
-+        number and location of bad blocks on NAND.
---- a/drivers/mtd/parsers/Makefile
-+++ b/drivers/mtd/parsers/Makefile
-@@ -10,5 +10,6 @@ ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)
- obj-$(CONFIG_MTD_PARSER_IMAGETAG)     += parser_imagetag.o
- obj-$(CONFIG_MTD_AFS_PARTS)           += afs.o
- obj-$(CONFIG_MTD_PARSER_TRX)          += parser_trx.o
-+obj-$(CONFIG_MTD_SERCOMM_PARTS)               += scpart.o
- obj-$(CONFIG_MTD_SHARPSL_PARTS)               += sharpslpart.o
- obj-$(CONFIG_MTD_REDBOOT_PARTS)               += redboot.o
---- /dev/null
-+++ b/drivers/mtd/parsers/scpart.c
-@@ -0,0 +1,248 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ *    drivers/mtd/scpart.c: Sercomm Partition Parser
-+ *
-+ *    Copyright (C) 2018 NOGUCHI Hiroshi
-+ *    Copyright (C) 2022 Mikhail Zhilkin
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/module.h>
-+
-+#define       MOD_NAME        "scpart"
-+
-+#ifdef pr_fmt
-+#undef pr_fmt
-+#endif
-+
-+#define pr_fmt(fmt) MOD_NAME ": " fmt
-+
-+#define       ID_ALREADY_FOUND        0xffffffffUL
-+
-+#define       MAP_OFFS_IN_BLK         0x800
-+#define       MAP_MIRROR_NUM          2
-+
-+static const char sc_part_magic[] = {
-+      'S', 'C', 'F', 'L', 'M', 'A', 'P', 'O', 'K', '\0',
-+};
-+#define       PART_MAGIC_LEN          sizeof(sc_part_magic)
-+
-+/* assumes that all fields are set by CPU native endian */
-+struct sc_part_desc {
-+      uint32_t        part_id;
-+      uint32_t        part_offs;
-+      uint32_t        part_bytes;
-+};
-+
-+static uint32_t scpart_desc_is_valid(struct sc_part_desc *pdesc)
-+{
-+      return ((pdesc->part_id != 0xffffffffUL) &&
-+              (pdesc->part_offs != 0xffffffffUL) &&
-+              (pdesc->part_bytes != 0xffffffffUL));
-+}
-+
-+static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs,
-+                             struct sc_part_desc **ppdesc)
-+{
-+      int cnt = 0;
-+      int res = 0;
-+      int res2;
-+      loff_t offs;
-+      size_t retlen;
-+      struct sc_part_desc *pdesc = NULL;
-+      struct sc_part_desc *tmpdesc;
-+      uint8_t *buf;
-+
-+      buf = kzalloc(master->erasesize, GFP_KERNEL);
-+      if (!buf) {
-+              res = -ENOMEM;
-+              goto out;
-+      }
-+
-+      res2 = mtd_read(master, partmap_offs, master->erasesize, &retlen, buf);
-+      if (res2 || retlen != master->erasesize) {
-+              res = -EIO;
-+              goto free;
-+      }
-+
-+      for (offs = MAP_OFFS_IN_BLK;
-+           offs < master->erasesize - sizeof(*tmpdesc);
-+           offs += sizeof(*tmpdesc)) {
-+              tmpdesc = (struct sc_part_desc *)&buf[offs];
-+              if (!scpart_desc_is_valid(tmpdesc))
-+                      break;
-+              cnt++;
-+      }
-+
-+      if (cnt > 0) {
-+              int bytes = cnt * sizeof(*pdesc);
-+
-+              pdesc = kcalloc(cnt, sizeof(*pdesc), GFP_KERNEL);
-+              if (!pdesc) {
-+                      res = -ENOMEM;
-+                      goto free;
-+              }
-+              memcpy(pdesc, &(buf[MAP_OFFS_IN_BLK]), bytes);
-+
-+              *ppdesc = pdesc;
-+              res = cnt;
-+      }
-+
-+free:
-+      kfree(buf);
-+
-+out:
-+      return res;
-+}
-+
-+static int scpart_find_partmap(struct mtd_info *master,
-+                             struct sc_part_desc **ppdesc)
-+{
-+      int magic_found = 0;
-+      int res = 0;
-+      int res2;
-+      loff_t offs = 0;
-+      size_t retlen;
-+      uint8_t rdbuf[PART_MAGIC_LEN];
-+
-+      while ((magic_found < MAP_MIRROR_NUM) &&
-+                      (offs < master->size) &&
-+                       !mtd_block_isbad(master, offs)) {
-+              res2 = mtd_read(master, offs, PART_MAGIC_LEN, &retlen, rdbuf);
-+              if (res2 || retlen != PART_MAGIC_LEN) {
-+                      res = -EIO;
-+                      goto out;
-+              }
-+              if (!memcmp(rdbuf, sc_part_magic, PART_MAGIC_LEN)) {
-+                      pr_debug("Signature found at 0x%llx\n", offs);
-+                      magic_found++;
-+                      res = scpart_scan_partmap(master, offs, ppdesc);
-+                      if (res > 0)
-+                              goto out;
-+              }
-+              offs += master->erasesize;
-+      }
-+
-+out:
-+      if (res > 0)
-+              pr_info("Valid 'SC PART MAP' (%d partitions) found at 0x%llx\n", res, offs);
-+      else
-+              pr_info("No valid 'SC PART MAP' was found\n");
-+
-+      return res;
-+}
-+
-+static int scpart_parse(struct mtd_info *master,
-+                      const struct mtd_partition **pparts,
-+                      struct mtd_part_parser_data *data)
-+{
-+      const char *partname;
-+      int n;
-+      int nr_scparts;
-+      int nr_parts = 0;
-+      int res = 0;
-+      struct sc_part_desc *scpart_map = NULL;
-+      struct mtd_partition *parts = NULL;
-+      struct device_node *mtd_node;
-+      struct device_node *ofpart_node;
-+      struct device_node *pp;
-+
-+      mtd_node = mtd_get_of_node(master);
-+      if (!mtd_node) {
-+              res = -ENOENT;
-+              goto out;
-+      }
-+
-+      ofpart_node = of_get_child_by_name(mtd_node, "partitions");
-+      if (!ofpart_node) {
-+              pr_info("%s: 'partitions' subnode not found on %pOF.\n",
-+                              master->name, mtd_node);
-+              res = -ENOENT;
-+              goto out;
-+      }
-+
-+      nr_scparts = scpart_find_partmap(master, &scpart_map);
-+      if (nr_scparts <= 0) {
-+              pr_info("No any partitions was found in 'SC PART MAP'.\n");
-+              res = -ENOENT;
-+              goto free;
-+      }
-+
-+      parts = kcalloc(of_get_child_count(ofpart_node), sizeof(*parts),
-+              GFP_KERNEL);
-+      if (!parts) {
-+              res = -ENOMEM;
-+              goto free;
-+      }
-+
-+      for_each_child_of_node(ofpart_node, pp) {
-+              u32 scpart_id;
-+
-+              if (of_property_read_u32(pp, "sercomm,scpart-id", &scpart_id))
-+                      continue;
-+
-+              for (n = 0 ; n < nr_scparts ; n++)
-+                      if ((scpart_map[n].part_id != ID_ALREADY_FOUND) &&
-+                                      (scpart_id == scpart_map[n].part_id))
-+                              break;
-+              if (n >= nr_scparts)
-+                      /* not match */
-+                      continue;
-+
-+              /* add the partition found in OF into MTD partition array */
-+              parts[nr_parts].offset = scpart_map[n].part_offs;
-+              parts[nr_parts].size = scpart_map[n].part_bytes;
-+              parts[nr_parts].of_node = pp;
-+
-+              if (!of_property_read_string(pp, "label", &partname))
-+                      parts[nr_parts].name = partname;
-+              if (of_property_read_bool(pp, "read-only"))
-+                      parts[nr_parts].mask_flags |= MTD_WRITEABLE;
-+              if (of_property_read_bool(pp, "lock"))
-+                      parts[nr_parts].mask_flags |= MTD_POWERUP_LOCK;
-+
-+              /* mark as 'done' */
-+              scpart_map[n].part_id = ID_ALREADY_FOUND;
-+
-+              nr_parts++;
-+      }
-+
-+      if (nr_parts > 0) {
-+              *pparts = parts;
-+              res = nr_parts;
-+      } else
-+              pr_info("No partition in OF matches partition ID with 'SC PART MAP'.\n");
-+
-+      of_node_put(pp);
-+
-+free:
-+      kfree(scpart_map);
-+      if (res <= 0)
-+              kfree(parts);
-+
-+out:
-+      return res;
-+}
-+
-+static const struct of_device_id scpart_parser_of_match_table[] = {
-+      { .compatible = "sercomm,sc-partitions" },
-+      {},
-+};
-+MODULE_DEVICE_TABLE(of, scpart_parser_of_match_table);
-+
-+static struct mtd_part_parser scpart_parser = {
-+      .parse_fn = scpart_parse,
-+      .name = "scpart",
-+      .of_match_table = scpart_parser_of_match_table,
-+};
-+module_mtd_part_parser(scpart_parser);
-+
-+/* mtd parsers will request the module by parser name */
-+MODULE_ALIAS("scpart");
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("NOGUCHI Hiroshi <drvlabo@gmail.com>");
-+MODULE_AUTHOR("Mikhail Zhilkin <csharper2005@gmail.com>");
-+MODULE_DESCRIPTION("Sercomm partition parser");