aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Suchanek <hramrach@gmail.com>2015-08-18 11:34:09 -0400
committerBrian Norris <computersforpeace@gmail.com>2015-10-30 17:01:39 -0400
commit5cfdedb7b9a0fe38aa4838bfe66fb9ebc2c9ce15 (patch)
treef9b6b8f882819bd02ed3df06baa4caea8222180e
parentfe2585e9c29a650af26824684e5033757fd6bc0c (diff)
mtd: ofpart: move ofpart partitions to a dedicated dt node
Parsing direct subnodes of a mtd device as partitions is unreliable since the mtd device is also part of its bus subsystem and can contain bus data in subnodes. Move ofpart data to a subnode of its own so it is clear which data is part of the partition layout. Signed-off-by: Michal Suchanek <hramrach@gmail.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/ofpart.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index aa26c32e1bc2..669c3452f278 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -29,23 +29,33 @@ static int parse_ofpart_partitions(struct mtd_info *master,
29 struct mtd_partition **pparts, 29 struct mtd_partition **pparts,
30 struct mtd_part_parser_data *data) 30 struct mtd_part_parser_data *data)
31{ 31{
32 struct device_node *node; 32 struct device_node *mtd_node;
33 struct device_node *ofpart_node;
33 const char *partname; 34 const char *partname;
34 struct device_node *pp; 35 struct device_node *pp;
35 int nr_parts, i; 36 int nr_parts, i, ret = 0;
37 bool dedicated = true;
36 38
37 39
38 if (!data) 40 if (!data)
39 return 0; 41 return 0;
40 42
41 node = data->of_node; 43 mtd_node = data->of_node;
42 if (!node) 44 if (!mtd_node)
43 return 0; 45 return 0;
44 46
47 ofpart_node = of_get_child_by_name(mtd_node, "partitions");
48 if (!ofpart_node) {
49 pr_warn("%s: 'partitions' subnode not found on %s. Trying to parse direct subnodes as partitions.\n",
50 master->name, mtd_node->full_name);
51 ofpart_node = mtd_node;
52 dedicated = false;
53 }
54
45 /* First count the subnodes */ 55 /* First count the subnodes */
46 nr_parts = 0; 56 nr_parts = 0;
47 for_each_child_of_node(node, pp) { 57 for_each_child_of_node(ofpart_node, pp) {
48 if (node_has_compatible(pp)) 58 if (!dedicated && node_has_compatible(pp))
49 continue; 59 continue;
50 60
51 nr_parts++; 61 nr_parts++;
@@ -59,22 +69,36 @@ static int parse_ofpart_partitions(struct mtd_info *master,
59 return -ENOMEM; 69 return -ENOMEM;
60 70
61 i = 0; 71 i = 0;
62 for_each_child_of_node(node, pp) { 72 for_each_child_of_node(ofpart_node, pp) {
63 const __be32 *reg; 73 const __be32 *reg;
64 int len; 74 int len;
65 int a_cells, s_cells; 75 int a_cells, s_cells;
66 76
67 if (node_has_compatible(pp)) 77 if (!dedicated && node_has_compatible(pp))
68 continue; 78 continue;
69 79
70 reg = of_get_property(pp, "reg", &len); 80 reg = of_get_property(pp, "reg", &len);
71 if (!reg) { 81 if (!reg) {
72 nr_parts--; 82 if (dedicated) {
73 continue; 83 pr_debug("%s: ofpart partition %s (%s) missing reg property.\n",
84 master->name, pp->full_name,
85 mtd_node->full_name);
86 goto ofpart_fail;
87 } else {
88 nr_parts--;
89 continue;
90 }
74 } 91 }
75 92
76 a_cells = of_n_addr_cells(pp); 93 a_cells = of_n_addr_cells(pp);
77 s_cells = of_n_size_cells(pp); 94 s_cells = of_n_size_cells(pp);
95 if (len / 4 != a_cells + s_cells) {
96 pr_debug("%s: ofpart partition %s (%s) error parsing reg property.\n",
97 master->name, pp->full_name,
98 mtd_node->full_name);
99 goto ofpart_fail;
100 }
101
78 (*pparts)[i].offset = of_read_number(reg, a_cells); 102 (*pparts)[i].offset = of_read_number(reg, a_cells);
79 (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); 103 (*pparts)[i].size = of_read_number(reg + a_cells, s_cells);
80 104
@@ -92,15 +116,20 @@ static int parse_ofpart_partitions(struct mtd_info *master,
92 i++; 116 i++;
93 } 117 }
94 118
95 if (!i) { 119 if (!nr_parts)
96 of_node_put(pp); 120 goto ofpart_none;
97 pr_err("No valid partition found on %s\n", node->full_name);
98 kfree(*pparts);
99 *pparts = NULL;
100 return -EINVAL;
101 }
102 121
103 return nr_parts; 122 return nr_parts;
123
124ofpart_fail:
125 pr_err("%s: error parsing ofpart partition %s (%s)\n",
126 master->name, pp->full_name, mtd_node->full_name);
127 ret = -EINVAL;
128ofpart_none:
129 of_node_put(pp);
130 kfree(*pparts);
131 *pparts = NULL;
132 return ret;
104} 133}
105 134
106static struct mtd_part_parser ofpart_parser = { 135static struct mtd_part_parser ofpart_parser = {