aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/physmap_of.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/physmap_of.c')
-rw-r--r--drivers/mtd/maps/physmap_of.c89
1 files changed, 27 insertions, 62 deletions
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index d4bcd3f8c57c..49acd4171893 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -80,65 +80,6 @@ static int parse_obsolete_partitions(struct of_device *dev,
80 80
81 return nr_parts; 81 return nr_parts;
82} 82}
83
84static int __devinit parse_partitions(struct of_flash *info,
85 struct of_device *dev)
86{
87 const char *partname;
88 static const char *part_probe_types[]
89 = { "cmdlinepart", "RedBoot", NULL };
90 struct device_node *dp = dev->node, *pp;
91 int nr_parts, i;
92
93 /* First look for RedBoot table or partitions on the command
94 * line, these take precedence over device tree information */
95 nr_parts = parse_mtd_partitions(info->mtd, part_probe_types,
96 &info->parts, 0);
97 if (nr_parts > 0)
98 return nr_parts;
99
100 /* First count the subnodes */
101 nr_parts = 0;
102 for (pp = of_get_next_child(dp, NULL); pp;
103 pp = of_get_next_child(dp, pp))
104 nr_parts++;
105
106 if (nr_parts == 0)
107 return parse_obsolete_partitions(dev, info, dp);
108
109 info->parts = kzalloc(nr_parts * sizeof(*info->parts),
110 GFP_KERNEL);
111 if (!info->parts)
112 return -ENOMEM;
113
114 for (pp = of_get_next_child(dp, NULL), i = 0; pp;
115 pp = of_get_next_child(dp, pp), i++) {
116 const u32 *reg;
117 int len;
118
119 reg = of_get_property(pp, "reg", &len);
120 if (!reg || (len != 2*sizeof(u32))) {
121 of_node_put(pp);
122 dev_err(&dev->dev, "Invalid 'reg' on %s\n",
123 dp->full_name);
124 kfree(info->parts);
125 info->parts = NULL;
126 return -EINVAL;
127 }
128 info->parts[i].offset = reg[0];
129 info->parts[i].size = reg[1];
130
131 partname = of_get_property(pp, "label", &len);
132 if (!partname)
133 partname = of_get_property(pp, "name", &len);
134 info->parts[i].name = (char *)partname;
135
136 if (of_get_property(pp, "read-only", &len))
137 info->parts[i].mask_flags = MTD_WRITEABLE;
138 }
139
140 return nr_parts;
141}
142#else /* MTD_PARTITIONS */ 83#else /* MTD_PARTITIONS */
143#define OF_FLASH_PARTS(info) (0) 84#define OF_FLASH_PARTS(info) (0)
144#define parse_partitions(info, dev) (0) 85#define parse_partitions(info, dev) (0)
@@ -213,6 +154,10 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
213static int __devinit of_flash_probe(struct of_device *dev, 154static int __devinit of_flash_probe(struct of_device *dev,
214 const struct of_device_id *match) 155 const struct of_device_id *match)
215{ 156{
157#ifdef CONFIG_MTD_PARTITIONS
158 static const char *part_probe_types[]
159 = { "cmdlinepart", "RedBoot", NULL };
160#endif
216 struct device_node *dp = dev->node; 161 struct device_node *dp = dev->node;
217 struct resource res; 162 struct resource res;
218 struct of_flash *info; 163 struct of_flash *info;
@@ -275,13 +220,33 @@ static int __devinit of_flash_probe(struct of_device *dev,
275 } 220 }
276 info->mtd->owner = THIS_MODULE; 221 info->mtd->owner = THIS_MODULE;
277 222
278 err = parse_partitions(info, dev); 223#ifdef CONFIG_MTD_PARTITIONS
224 /* First look for RedBoot table or partitions on the command
225 * line, these take precedence over device tree information */
226 err = parse_mtd_partitions(info->mtd, part_probe_types,
227 &info->parts, 0);
279 if (err < 0) 228 if (err < 0)
280 goto err_out; 229 return err;
230
231#ifdef CONFIG_MTD_OF_PARTS
232 if (err == 0) {
233 err = of_mtd_parse_partitions(&dev->dev, info->mtd,
234 dp, &info->parts);
235 if (err < 0)
236 return err;
237 }
238#endif
239
240 if (err == 0) {
241 err = parse_obsolete_partitions(dev, info, dp);
242 if (err < 0)
243 return err;
244 }
281 245
282 if (err > 0) 246 if (err > 0)
283 add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); 247 add_mtd_partitions(info->mtd, info->parts, err);
284 else 248 else
249#endif
285 add_mtd_device(info->mtd); 250 add_mtd_device(info->mtd);
286 251
287 return 0; 252 return 0;