diff options
author | Michal Suchanek <hramrach@gmail.com> | 2015-08-18 11:34:09 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2015-10-30 17:01:39 -0400 |
commit | 5cfdedb7b9a0fe38aa4838bfe66fb9ebc2c9ce15 (patch) | |
tree | f9b6b8f882819bd02ed3df06baa4caea8222180e | |
parent | fe2585e9c29a650af26824684e5033757fd6bc0c (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.c | 63 |
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 | |||
124 | ofpart_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; | ||
128 | ofpart_none: | ||
129 | of_node_put(pp); | ||
130 | kfree(*pparts); | ||
131 | *pparts = NULL; | ||
132 | return ret; | ||
104 | } | 133 | } |
105 | 134 | ||
106 | static struct mtd_part_parser ofpart_parser = { | 135 | static struct mtd_part_parser ofpart_parser = { |