diff options
Diffstat (limited to 'nixos/modules/kernel-patches/0044-mtd-mtdsplit-support.patch')
-rw-r--r-- | nixos/modules/kernel-patches/0044-mtd-mtdsplit-support.patch | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/nixos/modules/kernel-patches/0044-mtd-mtdsplit-support.patch b/nixos/modules/kernel-patches/0044-mtd-mtdsplit-support.patch deleted file mode 100644 index cf98c20..0000000 --- a/nixos/modules/kernel-patches/0044-mtd-mtdsplit-support.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 3048cf485cbb35e59865e1d841bfbb06a093987a Mon Sep 17 00:00:00 2001 -From: OpenWrt community <openwrt-devel@lists.openwrt.org> -Date: Wed, 13 Jul 2022 11:47:35 +0200 -Subject: [PATCH 44/96] mtd: mtdsplit support - ---- - drivers/mtd/Kconfig | 19 ++++ - drivers/mtd/Makefile | 2 + - drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++----- - include/linux/mtd/mtd.h | 25 +++++ - include/linux/mtd/partitions.h | 7 ++ - 5 files changed, 197 insertions(+), 25 deletions(-) - -diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig -index 796a2eccbef0..f9ed93c4cf0f 100644 ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,25 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+source "drivers/mtd/mtdsplit/Kconfig" -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m -diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile -index 593d0593a038..b14b7fe0f597 100644 ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o - - obj-y += parsers/ - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o - obj-$(CONFIG_MTD_BLOCK) += mtdblock.o -diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c -index d442fa94c872..f1ed12aae1fe 100644 ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -15,11 +15,13 @@ - #include <linux/kmod.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -+#include <linux/magic.h> - #include <linux/err.h> - #include <linux/of.h> - #include <linux/of_platform.h> - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* - * MTD methods which simply translate the effective address and pass through -@@ -236,6 +238,146 @@ static int mtd_add_partition_attrs(struct mtd_info *new) - return ret; - } - -+static DEFINE_SPINLOCK(part_parser_lock); -+static LIST_HEAD(part_parsers); -+ -+static struct mtd_part_parser *mtd_part_parser_get(const char *name) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ list_for_each_entry(p, &part_parsers, list) -+ if (!strcmp(p->name, name) && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static inline void mtd_part_parser_put(const struct mtd_part_parser *p) -+{ -+ module_put(p->owner); -+} -+ -+static struct mtd_part_parser * -+get_partition_parser_by_type(enum mtd_parser_type type, -+ struct mtd_part_parser *start) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ p = list_prepare_entry(start, &part_parsers, list); -+ if (start) -+ mtd_part_parser_put(start); -+ -+ list_for_each_entry_continue(p, &part_parsers, list) { -+ if (p->type == type && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_part_parser *prev = NULL; -+ int ret = 0; -+ -+ while (1) { -+ struct mtd_part_parser *parser; -+ -+ parser = get_partition_parser_by_type(type, prev); -+ if (!parser) -+ break; -+ -+ ret = (*parser->parse_fn)(master, pparts, data); -+ -+ if (ret > 0) { -+ mtd_part_parser_put(parser); -+ printk(KERN_NOTICE -+ "%d %s partitions found on MTD device %s\n", -+ ret, parser->name, master->name); -+ break; -+ } -+ -+ prev = parser; -+ } -+ -+ return ret; -+} -+ -+static int -+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) -+{ -+ struct mtd_partition *parts; -+ int nr_parts; -+ int i; -+ -+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts, -+ NULL); -+ if (nr_parts <= 0) -+ return nr_parts; -+ -+ if (WARN_ON(!parts)) -+ return 0; -+ -+ for (i = 0; i < nr_parts; i++) { -+ /* adjust partition offsets */ -+ parts[i].offset += child->part.offset; -+ -+ mtd_add_partition(child->parent, -+ parts[i].name, -+ parts[i].offset, -+ parts[i].size); -+ } -+ -+ kfree(parts); -+ -+ return nr_parts; -+} -+ -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_info *part) -+{ -+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (!strcmp(part->name, "rootfs")) { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ rootfs_found = 1; -+ } -+ -+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) && -+ !of_find_property(mtd_get_of_node(part), "compatible", NULL)) -+ split_firmware(master, part); -+} -+ - int mtd_add_partition(struct mtd_info *parent, const char *name, - long long offset, long long length) - { -@@ -274,6 +416,7 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, - if (ret) - goto err_remove_part; - -+ mtd_partition_split(parent, child); - mtd_add_partition_attrs(child); - - return 0; -@@ -422,6 +565,7 @@ int add_mtd_partitions(struct mtd_info *parent, - goto err_del_partitions; - } - -+ mtd_partition_split(master, child); - mtd_add_partition_attrs(child); - - /* Look for subpartitions */ -@@ -438,31 +582,6 @@ int add_mtd_partitions(struct mtd_info *parent, - return ret; - } - --static DEFINE_SPINLOCK(part_parser_lock); --static LIST_HEAD(part_parsers); -- --static struct mtd_part_parser *mtd_part_parser_get(const char *name) --{ -- struct mtd_part_parser *p, *ret = NULL; -- -- spin_lock(&part_parser_lock); -- -- list_for_each_entry(p, &part_parsers, list) -- if (!strcmp(p->name, name) && try_module_get(p->owner)) { -- ret = p; -- break; -- } -- -- spin_unlock(&part_parser_lock); -- -- return ret; --} -- --static inline void mtd_part_parser_put(const struct mtd_part_parser *p) --{ -- module_put(p->owner); --} -- - /* - * Many partition parsers just expected the core to kfree() all their data in - * one chunk. Do that by default. -diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h -index 955aee14b0f7..e2359a3569f0 100644 ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -608,6 +608,24 @@ static inline void mtd_align_erase_req(struct mtd_info *mtd, - req->len += mtd->erasesize - mod; - } - -+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round up to next erase block */ -+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -+} -+ -+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round down to the start of the current erase block */ -+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -+} -+ - static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) - { - if (mtd->writesize_shift) -@@ -680,6 +698,13 @@ extern void __put_mtd_device(struct mtd_info *mtd); - extern struct mtd_info *get_mtd_device_nm(const char *name); - extern void put_mtd_device(struct mtd_info *mtd); - -+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return 0; -+ -+ return mtd->part.offset; -+} - - struct mtd_notifier { - void (*add)(struct mtd_info *mtd); -diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h -index b74a539ec581..65ba0dbf961d 100644 ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -75,6 +75,12 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; -@@ -83,6 +89,7 @@ struct mtd_part_parser { - int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, - struct mtd_part_parser_data *); - void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -+ enum mtd_parser_type type; - }; - - /* Container for passing around a set of parsed partitions */ --- -2.37.2 - |