kernel: bump 4.9 to 4.9.206
[oweals/openwrt.git] / target / linux / generic / pending-4.9 / 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 @@ -744,6 +748,36 @@ int mtd_del_partition(struct mtd_info *m
24  }
25  EXPORT_SYMBOL_GPL(mtd_del_partition);
26  
27 +static int
28 +run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type)
29 +{
30 +       struct mtd_partition *parts;
31 +       int nr_parts;
32 +       int i;
33 +
34 +       nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, (const struct mtd_partition **)&parts,
35 +                                               NULL);
36 +       if (nr_parts <= 0)
37 +               return nr_parts;
38 +
39 +       if (WARN_ON(!parts))
40 +               return 0;
41 +
42 +       for (i = 0; i < nr_parts; i++) {
43 +               /* adjust partition offsets */
44 +               parts[i].offset += slave->offset;
45 +
46 +               mtd_add_partition(slave->parent,
47 +                                 parts[i].name,
48 +                                 parts[i].offset,
49 +                                 parts[i].size);
50 +       }
51 +
52 +       kfree(parts);
53 +
54 +       return nr_parts;
55 +}
56 +
57  #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
58  #define SPLIT_FIRMWARE_NAME    CONFIG_MTD_SPLIT_FIRMWARE_NAME
59  #else
60 @@ -1134,6 +1168,61 @@ void mtd_part_parser_cleanup(struct mtd_
61         }
62  }
63  
64 +static struct mtd_part_parser *
65 +get_partition_parser_by_type(enum mtd_parser_type type,
66 +                            struct mtd_part_parser *start)
67 +{
68 +       struct mtd_part_parser *p, *ret = NULL;
69 +
70 +       spin_lock(&part_parser_lock);
71 +
72 +       p = list_prepare_entry(start, &part_parsers, list);
73 +       if (start)
74 +               mtd_part_parser_put(start);
75 +
76 +       list_for_each_entry_continue(p, &part_parsers, list) {
77 +               if (p->type == type && try_module_get(p->owner)) {
78 +                       ret = p;
79 +                       break;
80 +               }
81 +       }
82 +
83 +       spin_unlock(&part_parser_lock);
84 +
85 +       return ret;
86 +}
87 +
88 +static int parse_mtd_partitions_by_type(struct mtd_info *master,
89 +                                       enum mtd_parser_type type,
90 +                                       const struct mtd_partition **pparts,
91 +                                       struct mtd_part_parser_data *data)
92 +{
93 +       struct mtd_part_parser *prev = NULL;
94 +       int ret = 0;
95 +
96 +       while (1) {
97 +               struct mtd_part_parser *parser;
98 +
99 +               parser = get_partition_parser_by_type(type, prev);
100 +               if (!parser)
101 +                       break;
102 +
103 +               ret = (*parser->parse_fn)(master, pparts, data);
104 +
105 +               if (ret > 0) {
106 +                       mtd_part_parser_put(parser);
107 +                       printk(KERN_NOTICE
108 +                              "%d %s partitions found on MTD device %s\n",
109 +                              ret, parser->name, master->name);
110 +                       break;
111 +               }
112 +
113 +               prev = parser;
114 +       }
115 +
116 +       return ret;
117 +}
118 +
119  int mtd_is_partition(const struct mtd_info *mtd)
120  {
121         struct mtd_part *part;
122 --- a/include/linux/mtd/partitions.h
123 +++ b/include/linux/mtd/partitions.h
124 @@ -73,6 +73,10 @@ struct mtd_part_parser_data {
125   * Functions dealing with the various ways of partitioning the space
126   */
127  
128 +enum mtd_parser_type {
129 +       MTD_PARSER_TYPE_DEVICE = 0,
130 +};
131 +
132  struct mtd_part_parser {
133         struct list_head list;
134         struct module *owner;
135 @@ -81,6 +85,7 @@ struct mtd_part_parser {
136         int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
137                         struct mtd_part_parser_data *);
138         void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
139 +       enum mtd_parser_type type;
140  };
141  
142  /* Container for passing around a set of parsed partitions */