kernel: use V10 of mtd patchset adding support for "compatible" string

In the commit bde5e7a632 ("kernel: backport mtd implementation for
"compatible" in "partitions" subnode") patches that got accepted into
l2-mtd.git were backported to the kernels 4.9 and 4.14. Unfortunately
there was a regression report, patches were dropped and never reached
4.16.

This commit replaces these pseudo-backports with the latest version
that includes regression fix and futher changes that were requested.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2018-03-14 15:07:03 +01:00
parent d88e928a44
commit ac9bcefa3b
14 changed files with 548 additions and 272 deletions

View file

@ -1,121 +0,0 @@
From bb2192123ec70470d6ea33f138846b175403a968 Mon Sep 17 00:00:00 2001
From: Brian Norris <computersforpeace@gmail.com>
Date: Thu, 4 Jan 2018 08:05:33 +0100
Subject: [PATCH] mtd: partitions: add of_match_table parser matching
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.
It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/mtd/mtdpart.c | 59 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/partitions.h | 1 +
2 files changed, 60 insertions(+)
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/err.h>
+#include <linux/of.h>
#include "mtdcore.h"
@@ -894,6 +895,45 @@ static int mtd_part_do_parse(struct mtd_
}
/**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+ struct mtd_part_parser *p, *ret = NULL;
+
+ spin_lock(&part_parser_lock);
+
+ list_for_each_entry(p, &part_parsers, list) {
+ const struct of_device_id *matches;
+
+ matches = p->of_match_table;
+ if (!matches)
+ continue;
+
+ for (; matches->compatible[0]; matches++) {
+ if (!strcmp(matches->compatible, compat) &&
+ try_module_get(p->owner)) {
+ ret = p;
+ break;
+ }
+ }
+
+ if (ret)
+ break;
+ }
+
+ spin_unlock(&part_parser_lock);
+
+ return ret;
+}
+
+/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
@@ -919,8 +959,27 @@ int parse_mtd_partitions(struct mtd_info
struct mtd_part_parser_data *data)
{
struct mtd_part_parser *parser;
+ struct device_node *np;
+ struct property *prop;
+ const char *compat;
int ret, err = 0;
+ np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+ of_property_for_each_string(np, "compatible", prop, compat) {
+ parser = mtd_part_get_compatible_parser(compat);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (ret > 0) {
+ of_node_put(np);
+ return 0;
+ }
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+ of_node_put(np);
+
if (!types)
types = default_mtd_part_types;
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
struct list_head list;
struct module *owner;
const char *name;
+ const struct of_device_id *of_match_table;
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);

View file

@ -1,121 +0,0 @@
From bb2192123ec70470d6ea33f138846b175403a968 Mon Sep 17 00:00:00 2001
From: Brian Norris <computersforpeace@gmail.com>
Date: Thu, 4 Jan 2018 08:05:33 +0100
Subject: [PATCH] mtd: partitions: add of_match_table parser matching
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.
It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/mtd/mtdpart.c | 59 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/partitions.h | 1 +
2 files changed, 60 insertions(+)
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/err.h>
+#include <linux/of.h>
#include "mtdcore.h"
@@ -886,6 +887,45 @@ static int mtd_part_do_parse(struct mtd_
}
/**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+ struct mtd_part_parser *p, *ret = NULL;
+
+ spin_lock(&part_parser_lock);
+
+ list_for_each_entry(p, &part_parsers, list) {
+ const struct of_device_id *matches;
+
+ matches = p->of_match_table;
+ if (!matches)
+ continue;
+
+ for (; matches->compatible[0]; matches++) {
+ if (!strcmp(matches->compatible, compat) &&
+ try_module_get(p->owner)) {
+ ret = p;
+ break;
+ }
+ }
+
+ if (ret)
+ break;
+ }
+
+ spin_unlock(&part_parser_lock);
+
+ return ret;
+}
+
+/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
@@ -911,8 +951,27 @@ int parse_mtd_partitions(struct mtd_info
struct mtd_part_parser_data *data)
{
struct mtd_part_parser *parser;
+ struct device_node *np;
+ struct property *prop;
+ const char *compat;
int ret, err = 0;
+ np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+ of_property_for_each_string(np, "compatible", prop, compat) {
+ parser = mtd_part_get_compatible_parser(compat);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (ret > 0) {
+ of_node_put(np);
+ return 0;
+ }
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+ of_node_put(np);
+
if (!types)
types = default_mtd_part_types;
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
struct list_head list;
struct module *owner;
const char *name;
+ const struct of_device_id *of_match_table;
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);

View file

@ -0,0 +1,194 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 30 Jan 2018 11:55:16 +0100
Subject: [PATCH V10 1/3] mtd: partitions: add of_match_table parser matching
for the "ofpart" type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In order to properly support compatibility strings as described in the
bindings/mtd/partition.txt "ofpart" type should be treated as an
indication for looking into OF. MTD should check "compatible" property
and search for a matching parser rather than blindly trying the one
supporting "fixed-partitions".
It also means that existing "fixed-partitions" parser should get renamed
to use a more meaningful name.
This commit achievies that aim by introducing a new mtd_part_of_parse().
It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
Please note that driver-specified parsers still take a precedence. It's
assumed that driver providing a parser type has a good reason for that
(e.g. having platform data with device-specific info). Also doing
otherwise could break existing setups. The same applies to using default
parsers (including "cmdlinepart") as some overwrite DT data with cmdline
argument.
Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.
This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Peter Rosin <peda@axentia.se>
---
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/err.h>
+#include <linux/of.h>
#include "mtdcore.h"
@@ -894,6 +895,92 @@ static int mtd_part_do_parse(struct mtd_
}
/**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+ struct mtd_part_parser *p, *ret = NULL;
+
+ spin_lock(&part_parser_lock);
+
+ list_for_each_entry(p, &part_parsers, list) {
+ const struct of_device_id *matches;
+
+ matches = p->of_match_table;
+ if (!matches)
+ continue;
+
+ for (; matches->compatible[0]; matches++) {
+ if (!strcmp(matches->compatible, compat) &&
+ try_module_get(p->owner)) {
+ ret = p;
+ break;
+ }
+ }
+
+ if (ret)
+ break;
+ }
+
+ spin_unlock(&part_parser_lock);
+
+ return ret;
+}
+
+static int mtd_part_of_parse(struct mtd_info *master,
+ struct mtd_partitions *pparts)
+{
+ struct mtd_part_parser *parser;
+ struct device_node *np;
+ struct property *prop;
+ const char *compat;
+ const char *fixed = "ofpart";
+ int ret, err = 0;
+
+ np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+ of_property_for_each_string(np, "compatible", prop, compat) {
+ parser = mtd_part_get_compatible_parser(compat);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, NULL);
+ if (ret > 0) {
+ of_node_put(np);
+ return ret;
+ }
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+ of_node_put(np);
+
+ /*
+ * For backward compatibility we have to try the "ofpart"
+ * parser. It supports old DT format with partitions specified as a
+ * direct subnodes of a flash device DT node without any compatibility
+ * specified we could match.
+ */
+ parser = mtd_part_parser_get(fixed);
+ if (!parser && !request_module("%s", fixed))
+ parser = mtd_part_parser_get(fixed);
+ if (parser) {
+ ret = mtd_part_do_parse(parser, master, pparts, NULL);
+ if (ret > 0)
+ return ret;
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+
+ return err;
+}
+
+/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
@@ -925,19 +1012,30 @@ int parse_mtd_partitions(struct mtd_info
types = default_mtd_part_types;
for ( ; *types; types++) {
- pr_debug("%s: parsing partitions %s\n", master->name, *types);
- parser = mtd_part_parser_get(*types);
- if (!parser && !request_module("%s", *types))
+ /*
+ * ofpart is a special type that means OF partitioning info
+ * should be used. It requires a bit different logic so it is
+ * handled in a separated function.
+ */
+ if (!strcmp(*types, "ofpart")) {
+ ret = mtd_part_of_parse(master, pparts);
+ } else {
+ pr_debug("%s: parsing partitions %s\n", master->name,
+ *types);
parser = mtd_part_parser_get(*types);
- pr_debug("%s: got parser %s\n", master->name,
- parser ? parser->name : NULL);
- if (!parser)
- continue;
- ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (!parser && !request_module("%s", *types))
+ parser = mtd_part_parser_get(*types);
+ pr_debug("%s: got parser %s\n", master->name,
+ parser ? parser->name : NULL);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (ret <= 0)
+ mtd_part_parser_put(parser);
+ }
/* Found partitions! */
if (ret > 0)
return 0;
- mtd_part_parser_put(parser);
/*
* Stash the first error we see; only report it if no parser
* succeeds
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
struct list_head list;
struct module *owner;
const char *name;
+ const struct of_device_id *of_match_table;
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);

View file

@ -0,0 +1,68 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 30 Jan 2018 12:09:58 +0100
Subject: [PATCH V10 2/3] mtd: rename "ofpart" parser to "fixed-partitions" as
it fits it better
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Type "ofpart" means that OF should be used to get partitioning info and
this driver supports "fixed-partitions" binding only. Renaming it should
lead to less confusion especially when parsers for new compatibility
strings start to appear.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -940,7 +940,7 @@ static int mtd_part_of_parse(struct mtd_
struct device_node *np;
struct property *prop;
const char *compat;
- const char *fixed = "ofpart";
+ const char *fixed = "fixed-partitions";
int ret, err = 0;
np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
@@ -960,7 +960,7 @@ static int mtd_part_of_parse(struct mtd_
of_node_put(np);
/*
- * For backward compatibility we have to try the "ofpart"
+ * For backward compatibility we have to try the "fixed-partitions"
* parser. It supports old DT format with partitions specified as a
* direct subnodes of a flash device DT node without any compatibility
* specified we could match.
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -25,9 +25,9 @@ static bool node_has_compatible(struct d
return of_get_property(pp, "compatible", NULL);
}
-static int parse_ofpart_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
+static int parse_fixed_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
{
struct mtd_partition *parts;
struct device_node *mtd_node;
@@ -141,8 +141,8 @@ ofpart_none:
}
static struct mtd_part_parser ofpart_parser = {
- .parse_fn = parse_ofpart_partitions,
- .name = "ofpart",
+ .parse_fn = parse_fixed_partitions,
+ .name = "fixed-partitions",
};
static int parse_ofoldpart_partitions(struct mtd_info *master,
@@ -229,4 +229,5 @@ MODULE_AUTHOR("Vitaly Wool, David Gibson
* with the same name. Since we provide the ofoldpart parser, we should have
* the corresponding alias.
*/
+MODULE_ALIAS("fixed-partitions");
MODULE_ALIAS("ofoldpart");

View file

@ -1,7 +1,7 @@
From 4ac9222778478a00c7fc9d347b7ed1e0e595120d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 4 Jan 2018 08:05:34 +0100 Date: Thu, 4 Jan 2018 08:05:34 +0100
Subject: [PATCH] mtd: ofpart: add of_match_table with "fixed-partitions" Subject: [PATCH V10 3/3] mtd: ofpart: add of_match_table with
"fixed-partitions"
MIME-Version: 1.0 MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit Content-Transfer-Encoding: 8bit
@ -17,10 +17,7 @@ This matches existing bindings documentation.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Brian Norris <computersforpeace@gmail.com> Reviewed-by: Brian Norris <computersforpeace@gmail.com>
Tested-by: Brian Norris <computersforpeace@gmail.com> Tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
--- ---
drivers/mtd/ofpart.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/mtd/ofpart.c --- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c
@ -35,8 +32,8 @@ Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table); +MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+ +
static struct mtd_part_parser ofpart_parser = { static struct mtd_part_parser ofpart_parser = {
.parse_fn = parse_ofpart_partitions, .parse_fn = parse_fixed_partitions,
.name = "ofpart", .name = "fixed-partitions",
+ .of_match_table = parse_ofpart_match_table, + .of_match_table = parse_ofpart_match_table,
}; };

View file

@ -137,9 +137,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
* Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
* are changing this array! * are changing this array!
*/ */
@@ -963,6 +990,13 @@ int parse_mtd_partitions(struct mtd_info @@ -1007,6 +1034,13 @@ int parse_mtd_partitions(struct mtd_info
struct property *prop; {
const char *compat; struct mtd_part_parser *parser;
int ret, err = 0; int ret, err = 0;
+ const char *const *types_of = NULL; + const char *const *types_of = NULL;
+ +
@ -149,9 +149,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ types = types_of; + types = types_of;
+ } + }
np = of_get_child_by_name(mtd_get_of_node(master), "partitions"); if (!types)
of_property_for_each_string(np, "compatible", prop, compat) { types = default_mtd_part_types;
@@ -1004,6 +1038,7 @@ int parse_mtd_partitions(struct mtd_info @@ -1043,6 +1077,7 @@ int parse_mtd_partitions(struct mtd_info
if (ret < 0 && !err) if (ret < 0 && !err)
err = ret; err = ret;
} }

View file

@ -9,7 +9,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -1093,6 +1093,62 @@ void mtd_part_parser_cleanup(struct mtd_ @@ -1132,6 +1132,62 @@ void mtd_part_parser_cleanup(struct mtd_
} }
} }

View file

@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
#else #else
@@ -1203,6 +1214,24 @@ int mtd_is_partition(const struct mtd_in @@ -1242,6 +1253,24 @@ int mtd_is_partition(const struct mtd_in
} }
EXPORT_SYMBOL_GPL(mtd_is_partition); EXPORT_SYMBOL_GPL(mtd_is_partition);

View file

@ -0,0 +1,194 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 30 Jan 2018 11:55:16 +0100
Subject: [PATCH V10 1/3] mtd: partitions: add of_match_table parser matching
for the "ofpart" type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In order to properly support compatibility strings as described in the
bindings/mtd/partition.txt "ofpart" type should be treated as an
indication for looking into OF. MTD should check "compatible" property
and search for a matching parser rather than blindly trying the one
supporting "fixed-partitions".
It also means that existing "fixed-partitions" parser should get renamed
to use a more meaningful name.
This commit achievies that aim by introducing a new mtd_part_of_parse().
It works by looking for a matching parser for every string in the
"compatibility" property (starting with the most specific one).
Please note that driver-specified parsers still take a precedence. It's
assumed that driver providing a parser type has a good reason for that
(e.g. having platform data with device-specific info). Also doing
otherwise could break existing setups. The same applies to using default
parsers (including "cmdlinepart") as some overwrite DT data with cmdline
argument.
Partition parsers can now provide an of_match_table to enable
flash<-->parser matching via device tree as documented in the
mtd/partition.txt.
This support is currently limited to built-in parsers as it uses
request_module() and friends. This should be sufficient for most cases
though as compiling parsers as modules isn't a common choice.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Peter Rosin <peda@axentia.se>
---
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -30,6 +30,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/err.h>
+#include <linux/of.h>
#include "mtdcore.h"
@@ -886,6 +887,92 @@ static int mtd_part_do_parse(struct mtd_
}
/**
+ * mtd_part_get_compatible_parser - find MTD parser by a compatible string
+ *
+ * @compat: compatible string describing partitions in a device tree
+ *
+ * MTD parsers can specify supported partitions by providing a table of
+ * compatibility strings. This function finds a parser that advertises support
+ * for a passed value of "compatible".
+ */
+static struct mtd_part_parser *mtd_part_get_compatible_parser(const char *compat)
+{
+ struct mtd_part_parser *p, *ret = NULL;
+
+ spin_lock(&part_parser_lock);
+
+ list_for_each_entry(p, &part_parsers, list) {
+ const struct of_device_id *matches;
+
+ matches = p->of_match_table;
+ if (!matches)
+ continue;
+
+ for (; matches->compatible[0]; matches++) {
+ if (!strcmp(matches->compatible, compat) &&
+ try_module_get(p->owner)) {
+ ret = p;
+ break;
+ }
+ }
+
+ if (ret)
+ break;
+ }
+
+ spin_unlock(&part_parser_lock);
+
+ return ret;
+}
+
+static int mtd_part_of_parse(struct mtd_info *master,
+ struct mtd_partitions *pparts)
+{
+ struct mtd_part_parser *parser;
+ struct device_node *np;
+ struct property *prop;
+ const char *compat;
+ const char *fixed = "ofpart";
+ int ret, err = 0;
+
+ np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
+ of_property_for_each_string(np, "compatible", prop, compat) {
+ parser = mtd_part_get_compatible_parser(compat);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, NULL);
+ if (ret > 0) {
+ of_node_put(np);
+ return ret;
+ }
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+ of_node_put(np);
+
+ /*
+ * For backward compatibility we have to try the "ofpart"
+ * parser. It supports old DT format with partitions specified as a
+ * direct subnodes of a flash device DT node without any compatibility
+ * specified we could match.
+ */
+ parser = mtd_part_parser_get(fixed);
+ if (!parser && !request_module("%s", fixed))
+ parser = mtd_part_parser_get(fixed);
+ if (parser) {
+ ret = mtd_part_do_parse(parser, master, pparts, NULL);
+ if (ret > 0)
+ return ret;
+ mtd_part_parser_put(parser);
+ if (ret < 0 && !err)
+ err = ret;
+ }
+
+ return err;
+}
+
+/**
* parse_mtd_partitions - parse MTD partitions
* @master: the master partition (describes whole MTD device)
* @types: names of partition parsers to try or %NULL
@@ -917,19 +1004,30 @@ int parse_mtd_partitions(struct mtd_info
types = default_mtd_part_types;
for ( ; *types; types++) {
- pr_debug("%s: parsing partitions %s\n", master->name, *types);
- parser = mtd_part_parser_get(*types);
- if (!parser && !request_module("%s", *types))
+ /*
+ * ofpart is a special type that means OF partitioning info
+ * should be used. It requires a bit different logic so it is
+ * handled in a separated function.
+ */
+ if (!strcmp(*types, "ofpart")) {
+ ret = mtd_part_of_parse(master, pparts);
+ } else {
+ pr_debug("%s: parsing partitions %s\n", master->name,
+ *types);
parser = mtd_part_parser_get(*types);
- pr_debug("%s: got parser %s\n", master->name,
- parser ? parser->name : NULL);
- if (!parser)
- continue;
- ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (!parser && !request_module("%s", *types))
+ parser = mtd_part_parser_get(*types);
+ pr_debug("%s: got parser %s\n", master->name,
+ parser ? parser->name : NULL);
+ if (!parser)
+ continue;
+ ret = mtd_part_do_parse(parser, master, pparts, data);
+ if (ret <= 0)
+ mtd_part_parser_put(parser);
+ }
/* Found partitions! */
if (ret > 0)
return 0;
- mtd_part_parser_put(parser);
/*
* Stash the first error we see; only report it if no parser
* succeeds
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -77,6 +77,7 @@ struct mtd_part_parser {
struct list_head list;
struct module *owner;
const char *name;
+ const struct of_device_id *of_match_table;
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);

View file

@ -0,0 +1,68 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 30 Jan 2018 12:09:58 +0100
Subject: [PATCH V10 2/3] mtd: rename "ofpart" parser to "fixed-partitions" as
it fits it better
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Type "ofpart" means that OF should be used to get partitioning info and
this driver supports "fixed-partitions" binding only. Renaming it should
lead to less confusion especially when parsers for new compatibility
strings start to appear.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -932,7 +932,7 @@ static int mtd_part_of_parse(struct mtd_
struct device_node *np;
struct property *prop;
const char *compat;
- const char *fixed = "ofpart";
+ const char *fixed = "fixed-partitions";
int ret, err = 0;
np = of_get_child_by_name(mtd_get_of_node(master), "partitions");
@@ -952,7 +952,7 @@ static int mtd_part_of_parse(struct mtd_
of_node_put(np);
/*
- * For backward compatibility we have to try the "ofpart"
+ * For backward compatibility we have to try the "fixed-partitions"
* parser. It supports old DT format with partitions specified as a
* direct subnodes of a flash device DT node without any compatibility
* specified we could match.
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -25,9 +25,9 @@ static bool node_has_compatible(struct d
return of_get_property(pp, "compatible", NULL);
}
-static int parse_ofpart_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
+static int parse_fixed_partitions(struct mtd_info *master,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
{
struct mtd_partition *parts;
struct device_node *mtd_node;
@@ -141,8 +141,8 @@ ofpart_none:
}
static struct mtd_part_parser ofpart_parser = {
- .parse_fn = parse_ofpart_partitions,
- .name = "ofpart",
+ .parse_fn = parse_fixed_partitions,
+ .name = "fixed-partitions",
};
static int parse_ofoldpart_partitions(struct mtd_info *master,
@@ -230,4 +230,5 @@ MODULE_AUTHOR("Vitaly Wool, David Gibson
* with the same name. Since we provide the ofoldpart parser, we should have
* the corresponding alias.
*/
+MODULE_ALIAS("fixed-partitions");
MODULE_ALIAS("ofoldpart");

View file

@ -1,7 +1,7 @@
From 4ac9222778478a00c7fc9d347b7ed1e0e595120d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 4 Jan 2018 08:05:34 +0100 Date: Thu, 4 Jan 2018 08:05:34 +0100
Subject: [PATCH] mtd: ofpart: add of_match_table with "fixed-partitions" Subject: [PATCH V10 3/3] mtd: ofpart: add of_match_table with
"fixed-partitions"
MIME-Version: 1.0 MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit Content-Transfer-Encoding: 8bit
@ -17,10 +17,7 @@ This matches existing bindings documentation.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Brian Norris <computersforpeace@gmail.com> Reviewed-by: Brian Norris <computersforpeace@gmail.com>
Tested-by: Brian Norris <computersforpeace@gmail.com> Tested-by: Brian Norris <computersforpeace@gmail.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
--- ---
drivers/mtd/ofpart.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/drivers/mtd/ofpart.c --- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c
@ -35,8 +32,8 @@ Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+MODULE_DEVICE_TABLE(of, parse_ofpart_match_table); +MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
+ +
static struct mtd_part_parser ofpart_parser = { static struct mtd_part_parser ofpart_parser = {
.parse_fn = parse_ofpart_partitions, .parse_fn = parse_fixed_partitions,
.name = "ofpart", .name = "fixed-partitions",
+ .of_match_table = parse_ofpart_match_table, + .of_match_table = parse_ofpart_match_table,
}; };

View file

@ -157,9 +157,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
* Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
* are changing this array! * are changing this array!
*/ */
@@ -955,6 +992,13 @@ int parse_mtd_partitions(struct mtd_info @@ -999,6 +1036,13 @@ int parse_mtd_partitions(struct mtd_info
struct property *prop; {
const char *compat; struct mtd_part_parser *parser;
int ret, err = 0; int ret, err = 0;
+ const char *const *types_of = NULL; + const char *const *types_of = NULL;
+ +
@ -169,9 +169,9 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ types = types_of; + types = types_of;
+ } + }
np = of_get_child_by_name(mtd_get_of_node(master), "partitions"); if (!types)
of_property_for_each_string(np, "compatible", prop, compat) { types = default_mtd_part_types;
@@ -996,6 +1040,7 @@ int parse_mtd_partitions(struct mtd_info @@ -1035,6 +1079,7 @@ int parse_mtd_partitions(struct mtd_info
if (ret < 0 && !err) if (ret < 0 && !err)
err = ret; err = ret;
} }

View file

@ -9,7 +9,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -1095,6 +1095,62 @@ void mtd_part_parser_cleanup(struct mtd_ @@ -1134,6 +1134,62 @@ void mtd_part_parser_cleanup(struct mtd_
} }
} }

View file

@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
#else #else
@@ -1205,6 +1216,24 @@ int mtd_is_partition(const struct mtd_in @@ -1244,6 +1255,24 @@ int mtd_is_partition(const struct mtd_in
} }
EXPORT_SYMBOL_GPL(mtd_is_partition); EXPORT_SYMBOL_GPL(mtd_is_partition);