mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 14:34:27 -05:00 
			
		
		
		
	These 2 patches were recently queued for 4.17. Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
		
			
				
	
	
		
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
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);
 |