diff options
Diffstat (limited to 'drivers/mtd/maps/physmap_of.c')
-rw-r--r-- | drivers/mtd/maps/physmap_of.c | 80 |
1 files changed, 7 insertions, 73 deletions
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index d251d1db129b..7d65f9d3e690 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -34,58 +34,10 @@ struct of_flash_list { | |||
34 | 34 | ||
35 | struct of_flash { | 35 | struct of_flash { |
36 | struct mtd_info *cmtd; | 36 | struct mtd_info *cmtd; |
37 | struct mtd_partition *parts; | ||
38 | int list_size; /* number of elements in of_flash_list */ | 37 | int list_size; /* number of elements in of_flash_list */ |
39 | struct of_flash_list list[0]; | 38 | struct of_flash_list list[0]; |
40 | }; | 39 | }; |
41 | 40 | ||
42 | #define OF_FLASH_PARTS(info) ((info)->parts) | ||
43 | static int parse_obsolete_partitions(struct platform_device *dev, | ||
44 | struct of_flash *info, | ||
45 | struct device_node *dp) | ||
46 | { | ||
47 | int i, plen, nr_parts; | ||
48 | const struct { | ||
49 | __be32 offset, len; | ||
50 | } *part; | ||
51 | const char *names; | ||
52 | |||
53 | part = of_get_property(dp, "partitions", &plen); | ||
54 | if (!part) | ||
55 | return 0; /* No partitions found */ | ||
56 | |||
57 | dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); | ||
58 | |||
59 | nr_parts = plen / sizeof(part[0]); | ||
60 | |||
61 | info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL); | ||
62 | if (!info->parts) | ||
63 | return -ENOMEM; | ||
64 | |||
65 | names = of_get_property(dp, "partition-names", &plen); | ||
66 | |||
67 | for (i = 0; i < nr_parts; i++) { | ||
68 | info->parts[i].offset = be32_to_cpu(part->offset); | ||
69 | info->parts[i].size = be32_to_cpu(part->len) & ~1; | ||
70 | if (be32_to_cpu(part->len) & 1) /* bit 0 set signifies read only partition */ | ||
71 | info->parts[i].mask_flags = MTD_WRITEABLE; | ||
72 | |||
73 | if (names && (plen > 0)) { | ||
74 | int len = strlen(names) + 1; | ||
75 | |||
76 | info->parts[i].name = (char *)names; | ||
77 | plen -= len; | ||
78 | names += len; | ||
79 | } else { | ||
80 | info->parts[i].name = "unnamed"; | ||
81 | } | ||
82 | |||
83 | part++; | ||
84 | } | ||
85 | |||
86 | return nr_parts; | ||
87 | } | ||
88 | |||
89 | static int of_flash_remove(struct platform_device *dev) | 41 | static int of_flash_remove(struct platform_device *dev) |
90 | { | 42 | { |
91 | struct of_flash *info; | 43 | struct of_flash *info; |
@@ -101,11 +53,8 @@ static int of_flash_remove(struct platform_device *dev) | |||
101 | mtd_concat_destroy(info->cmtd); | 53 | mtd_concat_destroy(info->cmtd); |
102 | } | 54 | } |
103 | 55 | ||
104 | if (info->cmtd) { | 56 | if (info->cmtd) |
105 | if (OF_FLASH_PARTS(info)) | ||
106 | kfree(OF_FLASH_PARTS(info)); | ||
107 | mtd_device_unregister(info->cmtd); | 57 | mtd_device_unregister(info->cmtd); |
108 | } | ||
109 | 58 | ||
110 | for (i = 0; i < info->list_size; i++) { | 59 | for (i = 0; i < info->list_size; i++) { |
111 | if (info->list[i].mtd) | 60 | if (info->list[i].mtd) |
@@ -165,7 +114,8 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, | |||
165 | specifies the list of partition probers to use. If none is given then the | 114 | specifies the list of partition probers to use. If none is given then the |
166 | default is use. These take precedence over other device tree | 115 | default is use. These take precedence over other device tree |
167 | information. */ | 116 | information. */ |
168 | static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL }; | 117 | static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", |
118 | "ofpart", "ofoldpart", NULL }; | ||
169 | static const char ** __devinit of_get_probes(struct device_node *dp) | 119 | static const char ** __devinit of_get_probes(struct device_node *dp) |
170 | { | 120 | { |
171 | const char *cp; | 121 | const char *cp; |
@@ -218,6 +168,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
218 | int reg_tuple_size; | 168 | int reg_tuple_size; |
219 | struct mtd_info **mtd_list = NULL; | 169 | struct mtd_info **mtd_list = NULL; |
220 | resource_size_t res_size; | 170 | resource_size_t res_size; |
171 | struct mtd_part_parser_data ppdata; | ||
221 | 172 | ||
222 | match = of_match_device(of_flash_match, &dev->dev); | 173 | match = of_match_device(of_flash_match, &dev->dev); |
223 | if (!match) | 174 | if (!match) |
@@ -331,29 +282,12 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
331 | if (err) | 282 | if (err) |
332 | goto err_out; | 283 | goto err_out; |
333 | 284 | ||
285 | ppdata.of_node = dp; | ||
334 | part_probe_types = of_get_probes(dp); | 286 | part_probe_types = of_get_probes(dp); |
335 | err = parse_mtd_partitions(info->cmtd, part_probe_types, | 287 | mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata, |
336 | &info->parts, 0); | 288 | NULL, 0); |
337 | if (err < 0) { | ||
338 | of_free_probes(part_probe_types); | ||
339 | goto err_out; | ||
340 | } | ||
341 | of_free_probes(part_probe_types); | 289 | of_free_probes(part_probe_types); |
342 | 290 | ||
343 | if (err == 0) { | ||
344 | err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); | ||
345 | if (err < 0) | ||
346 | goto err_out; | ||
347 | } | ||
348 | |||
349 | if (err == 0) { | ||
350 | err = parse_obsolete_partitions(dev, info, dp); | ||
351 | if (err < 0) | ||
352 | goto err_out; | ||
353 | } | ||
354 | |||
355 | mtd_device_register(info->cmtd, info->parts, err); | ||
356 | |||
357 | kfree(mtd_list); | 291 | kfree(mtd_list); |
358 | 292 | ||
359 | return 0; | 293 | return 0; |