kernel: use add_mtd_partitions() helper when using OpenWrt parsers
[openwrt/staging/wigyori.git] / target / linux / generic / pending-4.14 / 401-mtd-add-support-for-different-partition-parser-types.patch
1 From: Gabor Juhos <juhosg@openwrt.org>
2 Subject: mtd: add support for different partition parser types
3
4 Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
5 ---
6 drivers/mtd/mtdpart.c | 56 ++++++++++++++++++++++++++++++++++++++++
7 include/linux/mtd/partitions.h | 11 ++++++++
8 2 files changed, 67 insertions(+)
9
10 --- a/drivers/mtd/mtdpart.c
11 +++ b/drivers/mtd/mtdpart.c
12 @@ -56,6 +56,10 @@ struct mtd_part {
13 };
14
15 static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part);
16 +static int parse_mtd_partitions_by_type(struct mtd_info *master,
17 + enum mtd_parser_type type,
18 + const struct mtd_partition **pparts,
19 + struct mtd_part_parser_data *data);
20
21 /*
22 * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
23 @@ -751,6 +755,28 @@ int mtd_del_partition(struct mtd_info *m
24 }
25 EXPORT_SYMBOL_GPL(mtd_del_partition);
26
27 +static int run_parsers_by_type(struct mtd_part *slave,
28 + enum mtd_parser_type type)
29 +{
30 + const struct mtd_partition *parts;
31 + int nr_parts;
32 + int err;
33 +
34 + nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, &parts,
35 + NULL);
36 + if (nr_parts <= 0)
37 + return nr_parts;
38 +
39 + if (WARN_ON(!parts))
40 + return 0;
41 +
42 + err = add_mtd_partitions(&slave->mtd, parts, nr_parts);
43 +
44 + kfree(parts);
45 +
46 + return err ? err : nr_parts;
47 +}
48 +
49 #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
50 #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
51 #else
52 @@ -1122,6 +1148,61 @@ void mtd_part_parser_cleanup(struct mtd_
53 }
54 }
55
56 +static struct mtd_part_parser *
57 +get_partition_parser_by_type(enum mtd_parser_type type,
58 + struct mtd_part_parser *start)
59 +{
60 + struct mtd_part_parser *p, *ret = NULL;
61 +
62 + spin_lock(&part_parser_lock);
63 +
64 + p = list_prepare_entry(start, &part_parsers, list);
65 + if (start)
66 + mtd_part_parser_put(start);
67 +
68 + list_for_each_entry_continue(p, &part_parsers, list) {
69 + if (p->type == type && try_module_get(p->owner)) {
70 + ret = p;
71 + break;
72 + }
73 + }
74 +
75 + spin_unlock(&part_parser_lock);
76 +
77 + return ret;
78 +}
79 +
80 +static int parse_mtd_partitions_by_type(struct mtd_info *master,
81 + enum mtd_parser_type type,
82 + const struct mtd_partition **pparts,
83 + struct mtd_part_parser_data *data)
84 +{
85 + struct mtd_part_parser *prev = NULL;
86 + int ret = 0;
87 +
88 + while (1) {
89 + struct mtd_part_parser *parser;
90 +
91 + parser = get_partition_parser_by_type(type, prev);
92 + if (!parser)
93 + break;
94 +
95 + ret = (*parser->parse_fn)(master, pparts, data);
96 +
97 + if (ret > 0) {
98 + mtd_part_parser_put(parser);
99 + printk(KERN_NOTICE
100 + "%d %s partitions found on MTD device %s\n",
101 + ret, parser->name, master->name);
102 + break;
103 + }
104 +
105 + prev = parser;
106 + }
107 +
108 + return ret;
109 +}
110 +
111 int mtd_is_partition(const struct mtd_info *mtd)
112 {
113 struct mtd_part *part;
114 --- a/include/linux/mtd/partitions.h
115 +++ b/include/linux/mtd/partitions.h
116 @@ -73,6 +73,10 @@ struct mtd_part_parser_data {
117 * Functions dealing with the various ways of partitioning the space
118 */
119
120 +enum mtd_parser_type {
121 + MTD_PARSER_TYPE_DEVICE = 0,
122 +};
123 +
124 struct mtd_part_parser {
125 struct list_head list;
126 struct module *owner;
127 @@ -81,6 +85,7 @@ struct mtd_part_parser {
128 int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
129 struct mtd_part_parser_data *);
130 void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
131 + enum mtd_parser_type type;
132 };
133
134 /* Container for passing around a set of parsed partitions */