diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2007-09-19 21:22:25 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@linux.vnet.ibm.com> | 2007-09-20 08:37:16 -0400 |
commit | c4d5e375470862fd741f93bf0686d7ac2f7fdce4 (patch) | |
tree | 8a82ce5fadde3c8a752f1080b427ef3c4c45e3d7 /drivers/mtd | |
parent | bd0076cc330f303905018a17d9dcfbabde497572 (diff) |
[POWERPC] Cleanups for physmap_of.c (v2)
This patch includes a whole batch of smallish cleanups for
drivers/mtd/physmap_of.c.
- A bunch of uneeded #includes are removed
- We switch to the modern linux/of.h etc. in place of
asm/prom.h
- Use some helper macros to avoid some ugly inline #ifdefs
- A few lines of unreachable code are removed
- A number of indentation / line-wrapping fixes
- More consistent use of kernel idioms such as if (!p) instead
of if (p == NULL)
- Clarify some printk()s and other informative strings.
- parse_obsolete_partitions() now returns 0 if no partition
information is found, instead of returning -ENOENT which the caller
had to handle specially.
- (the big one) Despite the name, this driver really has
nothing to do with drivers/mtd/physmap.c. The fact that the flash
chips must be physically direct mapped is a constrant, but doesn't
really say anything about the actual purpose of this driver, which is
to instantiate MTD devices based on information from the device tree.
Therefore the physmap name is replaced everywhere within the file with
"of_flash". The file itself and the Kconfig option is not renamed for
now (so that the diff is actually a diff). That can come later.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/maps/physmap_of.c | 224 |
1 files changed, 99 insertions, 125 deletions
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 096dd47b5d5d..cf75a566442e 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Normal mappings of chips in physical memory for OF devices | 2 | * Flash mappings described by the OF (or flattened) device tree |
3 | * | 3 | * |
4 | * Copyright (C) 2006 MontaVista Software Inc. | 4 | * Copyright (C) 2006 MontaVista Software Inc. |
5 | * Author: Vitaly Wool <vwool@ru.mvista.com> | 5 | * Author: Vitaly Wool <vwool@ru.mvista.com> |
@@ -15,20 +15,15 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | #include <linux/slab.h> | ||
21 | #include <linux/device.h> | 19 | #include <linux/device.h> |
22 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
23 | #include <linux/mtd/map.h> | 21 | #include <linux/mtd/map.h> |
24 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
25 | #include <linux/mtd/physmap.h> | 23 | #include <linux/of.h> |
26 | #include <asm/io.h> | 24 | #include <linux/of_platform.h> |
27 | #include <asm/prom.h> | ||
28 | #include <asm/of_device.h> | ||
29 | #include <asm/of_platform.h> | ||
30 | 25 | ||
31 | struct physmap_flash_info { | 26 | struct of_flash { |
32 | struct mtd_info *mtd; | 27 | struct mtd_info *mtd; |
33 | struct map_info map; | 28 | struct map_info map; |
34 | struct resource *res; | 29 | struct resource *res; |
@@ -38,8 +33,10 @@ struct physmap_flash_info { | |||
38 | }; | 33 | }; |
39 | 34 | ||
40 | #ifdef CONFIG_MTD_PARTITIONS | 35 | #ifdef CONFIG_MTD_PARTITIONS |
36 | #define OF_FLASH_PARTS(info) ((info)->parts) | ||
37 | |||
41 | static int parse_obsolete_partitions(struct of_device *dev, | 38 | static int parse_obsolete_partitions(struct of_device *dev, |
42 | struct physmap_flash_info *info, | 39 | struct of_flash *info, |
43 | struct device_node *dp) | 40 | struct device_node *dp) |
44 | { | 41 | { |
45 | int i, plen, nr_parts; | 42 | int i, plen, nr_parts; |
@@ -50,17 +47,15 @@ static int parse_obsolete_partitions(struct of_device *dev, | |||
50 | 47 | ||
51 | part = of_get_property(dp, "partitions", &plen); | 48 | part = of_get_property(dp, "partitions", &plen); |
52 | if (!part) | 49 | if (!part) |
53 | return -ENOENT; | 50 | return 0; /* No partitions found */ |
54 | 51 | ||
55 | dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); | 52 | dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); |
56 | 53 | ||
57 | nr_parts = plen / sizeof(part[0]); | 54 | nr_parts = plen / sizeof(part[0]); |
58 | 55 | ||
59 | info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL); | 56 | info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL); |
60 | if (!info->parts) { | 57 | if (!info->parts) |
61 | printk(KERN_ERR "Can't allocate the flash partition data!\n"); | ||
62 | return -ENOMEM; | 58 | return -ENOMEM; |
63 | } | ||
64 | 59 | ||
65 | names = of_get_property(dp, "partition-names", &plen); | 60 | names = of_get_property(dp, "partition-names", &plen); |
66 | 61 | ||
@@ -86,8 +81,8 @@ static int parse_obsolete_partitions(struct of_device *dev, | |||
86 | return nr_parts; | 81 | return nr_parts; |
87 | } | 82 | } |
88 | 83 | ||
89 | static int __devinit process_partitions(struct physmap_flash_info *info, | 84 | static int __devinit parse_partitions(struct of_flash *info, |
90 | struct of_device *dev) | 85 | struct of_device *dev) |
91 | { | 86 | { |
92 | const char *partname; | 87 | const char *partname; |
93 | static const char *part_probe_types[] | 88 | static const char *part_probe_types[] |
@@ -109,89 +104,68 @@ static int __devinit process_partitions(struct physmap_flash_info *info, | |||
109 | for (pp = dp->child; pp; pp = pp->sibling) | 104 | for (pp = dp->child; pp; pp = pp->sibling) |
110 | nr_parts++; | 105 | nr_parts++; |
111 | 106 | ||
112 | if (nr_parts) { | 107 | if (nr_parts == 0) |
113 | info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), | 108 | return parse_obsolete_partitions(dev, info, dp); |
114 | GFP_KERNEL); | 109 | |
115 | if (!info->parts) { | 110 | info->parts = kzalloc(nr_parts * sizeof(*info->parts), |
116 | printk(KERN_ERR "Can't allocate the flash partition data!\n"); | 111 | GFP_KERNEL); |
117 | return -ENOMEM; | 112 | if (!info->parts) |
118 | } | 113 | return -ENOMEM; |
119 | 114 | ||
120 | for (pp = dp->child, i = 0 ; pp; pp = pp->sibling, i++) { | 115 | for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) { |
121 | const u32 *reg; | 116 | const u32 *reg; |
122 | int len; | 117 | int len; |
123 | 118 | ||
124 | reg = of_get_property(pp, "reg", &len); | 119 | reg = of_get_property(pp, "reg", &len); |
125 | if (!reg || (len != 2*sizeof(u32))) { | 120 | if (!reg || (len != 2*sizeof(u32))) { |
126 | dev_err(&dev->dev, "Invalid 'reg' on %s\n", | 121 | dev_err(&dev->dev, "Invalid 'reg' on %s\n", |
127 | dp->full_name); | 122 | dp->full_name); |
128 | kfree(info->parts); | 123 | kfree(info->parts); |
129 | info->parts = NULL; | 124 | info->parts = NULL; |
130 | return -EINVAL; | 125 | return -EINVAL; |
131 | } | ||
132 | info->parts[i].offset = reg[0]; | ||
133 | info->parts[i].size = reg[1]; | ||
134 | |||
135 | partname = of_get_property(pp, "label", &len); | ||
136 | if (!partname) | ||
137 | partname = of_get_property(pp, "name", &len); | ||
138 | info->parts[i].name = (char *)partname; | ||
139 | |||
140 | if (of_get_property(pp, "read-only", &len)) | ||
141 | info->parts[i].mask_flags = MTD_WRITEABLE; | ||
142 | } | 126 | } |
143 | } else { | 127 | info->parts[i].offset = reg[0]; |
144 | nr_parts = parse_obsolete_partitions(dev, info, dp); | 128 | info->parts[i].size = reg[1]; |
145 | if (nr_parts == -ENOENT) | ||
146 | nr_parts = 0; | ||
147 | } | ||
148 | 129 | ||
149 | if (nr_parts < 0) | 130 | partname = of_get_property(pp, "label", &len); |
150 | return nr_parts; | 131 | if (!partname) |
132 | partname = of_get_property(pp, "name", &len); | ||
133 | info->parts[i].name = (char *)partname; | ||
151 | 134 | ||
152 | if (nr_parts > 0) | 135 | if (of_get_property(pp, "read-only", &len)) |
153 | add_mtd_partitions(info->mtd, info->parts, nr_parts); | 136 | info->parts[i].mask_flags = MTD_WRITEABLE; |
154 | else | 137 | } |
155 | add_mtd_device(info->mtd); | ||
156 | 138 | ||
157 | return 0; | 139 | return nr_parts; |
158 | } | 140 | } |
159 | #else /* MTD_PARTITIONS */ | 141 | #else /* MTD_PARTITIONS */ |
160 | static int __devinit process_partitions(struct physmap_flash_info *info, | 142 | #define OF_FLASH_PARTS(info) (0) |
161 | struct device_node *dev) | 143 | #define parse_partitions(info, dev) (0) |
162 | { | ||
163 | add_mtd_device(info->mtd); | ||
164 | return 0; | ||
165 | } | ||
166 | #endif /* MTD_PARTITIONS */ | 144 | #endif /* MTD_PARTITIONS */ |
167 | 145 | ||
168 | static int of_physmap_remove(struct of_device *dev) | 146 | static int of_flash_remove(struct of_device *dev) |
169 | { | 147 | { |
170 | struct physmap_flash_info *info; | 148 | struct of_flash *info; |
171 | 149 | ||
172 | info = dev_get_drvdata(&dev->dev); | 150 | info = dev_get_drvdata(&dev->dev); |
173 | if (info == NULL) | 151 | if (!info) |
174 | return 0; | 152 | return 0; |
175 | dev_set_drvdata(&dev->dev, NULL); | 153 | dev_set_drvdata(&dev->dev, NULL); |
176 | 154 | ||
177 | if (info->mtd != NULL) { | 155 | if (info->mtd) { |
178 | #ifdef CONFIG_MTD_PARTITIONS | 156 | if (OF_FLASH_PARTS(info)) { |
179 | if (info->parts) { | ||
180 | del_mtd_partitions(info->mtd); | 157 | del_mtd_partitions(info->mtd); |
181 | kfree(info->parts); | 158 | kfree(OF_FLASH_PARTS(info)); |
182 | } else { | 159 | } else { |
183 | del_mtd_device(info->mtd); | 160 | del_mtd_device(info->mtd); |
184 | } | 161 | } |
185 | #else | ||
186 | del_mtd_device(info->mtd); | ||
187 | #endif | ||
188 | map_destroy(info->mtd); | 162 | map_destroy(info->mtd); |
189 | } | 163 | } |
190 | 164 | ||
191 | if (info->map.virt != NULL) | 165 | if (info->map.virt) |
192 | iounmap(info->map.virt); | 166 | iounmap(info->map.virt); |
193 | 167 | ||
194 | if (info->res != NULL) { | 168 | if (info->res) { |
195 | release_resource(info->res); | 169 | release_resource(info->res); |
196 | kfree(info->res); | 170 | kfree(info->res); |
197 | } | 171 | } |
@@ -229,52 +203,49 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, | |||
229 | return do_map_probe("jedec_probe", map); | 203 | return do_map_probe("jedec_probe", map); |
230 | } else { | 204 | } else { |
231 | if (strcmp(of_probe, "ROM") != 0) | 205 | if (strcmp(of_probe, "ROM") != 0) |
232 | dev_dbg(&dev->dev, "obsolete_probe: don't know probe type " | 206 | dev_warn(&dev->dev, "obsolete_probe: don't know probe " |
233 | "'%s', mapping as rom\n", of_probe); | 207 | "type '%s', mapping as rom\n", of_probe); |
234 | return do_map_probe("mtd_rom", map); | 208 | return do_map_probe("mtd_rom", map); |
235 | } | 209 | } |
236 | } | 210 | } |
237 | 211 | ||
238 | static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) | 212 | static int __devinit of_flash_probe(struct of_device *dev, |
213 | const struct of_device_id *match) | ||
239 | { | 214 | { |
240 | struct device_node *dp = dev->node; | 215 | struct device_node *dp = dev->node; |
241 | struct resource res; | 216 | struct resource res; |
242 | struct physmap_flash_info *info; | 217 | struct of_flash *info; |
243 | const char *probe_type = (const char *)match->data; | 218 | const char *probe_type = match->data; |
244 | const u32 *width; | 219 | const u32 *width; |
245 | int err; | 220 | int err; |
246 | 221 | ||
222 | err = -ENXIO; | ||
247 | if (of_address_to_resource(dp, 0, &res)) { | 223 | if (of_address_to_resource(dp, 0, &res)) { |
248 | dev_err(&dev->dev, "Can't get the flash mapping!\n"); | 224 | dev_err(&dev->dev, "Can't get IO address from device tree\n"); |
249 | err = -EINVAL; | ||
250 | goto err_out; | 225 | goto err_out; |
251 | } | 226 | } |
252 | 227 | ||
253 | dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n", | 228 | dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", |
254 | (unsigned long long)res.end - res.start + 1, | 229 | (unsigned long long)res.start, (unsigned long long)res.end); |
255 | (unsigned long long)res.start); | ||
256 | 230 | ||
257 | info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); | 231 | err = -ENOMEM; |
258 | if (info == NULL) { | 232 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
259 | err = -ENOMEM; | 233 | if (!info) |
260 | goto err_out; | 234 | goto err_out; |
261 | } | ||
262 | memset(info, 0, sizeof(*info)); | 235 | memset(info, 0, sizeof(*info)); |
263 | 236 | ||
264 | dev_set_drvdata(&dev->dev, info); | 237 | dev_set_drvdata(&dev->dev, info); |
265 | 238 | ||
239 | err = -EBUSY; | ||
266 | info->res = request_mem_region(res.start, res.end - res.start + 1, | 240 | info->res = request_mem_region(res.start, res.end - res.start + 1, |
267 | dev->dev.bus_id); | 241 | dev->dev.bus_id); |
268 | if (info->res == NULL) { | 242 | if (!info->res) |
269 | dev_err(&dev->dev, "Could not reserve memory region\n"); | ||
270 | err = -ENOMEM; | ||
271 | goto err_out; | 243 | goto err_out; |
272 | } | ||
273 | 244 | ||
245 | err = -ENXIO; | ||
274 | width = of_get_property(dp, "bank-width", NULL); | 246 | width = of_get_property(dp, "bank-width", NULL); |
275 | if (width == NULL) { | 247 | if (!width) { |
276 | dev_err(&dev->dev, "Can't get the flash bank width!\n"); | 248 | dev_err(&dev->dev, "Can't get bank width from device tree\n"); |
277 | err = -EINVAL; | ||
278 | goto err_out; | 249 | goto err_out; |
279 | } | 250 | } |
280 | 251 | ||
@@ -283,10 +254,10 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev | |||
283 | info->map.size = res.end - res.start + 1; | 254 | info->map.size = res.end - res.start + 1; |
284 | info->map.bankwidth = *width; | 255 | info->map.bankwidth = *width; |
285 | 256 | ||
257 | err = -ENOMEM; | ||
286 | info->map.virt = ioremap(info->map.phys, info->map.size); | 258 | info->map.virt = ioremap(info->map.phys, info->map.size); |
287 | if (info->map.virt == NULL) { | 259 | if (!info->map.virt) { |
288 | dev_err(&dev->dev, "Failed to ioremap flash region\n"); | 260 | dev_err(&dev->dev, "Failed to ioremap() flash region\n"); |
289 | err = EIO; | ||
290 | goto err_out; | 261 | goto err_out; |
291 | } | 262 | } |
292 | 263 | ||
@@ -297,25 +268,30 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev | |||
297 | else | 268 | else |
298 | info->mtd = obsolete_probe(dev, &info->map); | 269 | info->mtd = obsolete_probe(dev, &info->map); |
299 | 270 | ||
300 | if (info->mtd == NULL) { | 271 | err = -ENXIO; |
301 | dev_err(&dev->dev, "map_probe failed\n"); | 272 | if (!info->mtd) { |
302 | err = -ENXIO; | 273 | dev_err(&dev->dev, "do_map_probe() failed\n"); |
303 | goto err_out; | 274 | goto err_out; |
304 | } | 275 | } |
305 | info->mtd->owner = THIS_MODULE; | 276 | info->mtd->owner = THIS_MODULE; |
306 | 277 | ||
307 | return process_partitions(info, dev); | 278 | err = parse_partitions(info, dev); |
279 | if (err < 0) | ||
280 | goto err_out; | ||
308 | 281 | ||
309 | err_out: | 282 | if (err > 0) |
310 | of_physmap_remove(dev); | 283 | add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); |
311 | return err; | 284 | else |
285 | add_mtd_device(info->mtd); | ||
312 | 286 | ||
313 | return 0; | 287 | return 0; |
314 | 288 | ||
315 | 289 | err_out: | |
290 | of_flash_remove(dev); | ||
291 | return err; | ||
316 | } | 292 | } |
317 | 293 | ||
318 | static struct of_device_id of_physmap_match[] = { | 294 | static struct of_device_id of_flash_match[] = { |
319 | { | 295 | { |
320 | .compatible = "cfi-flash", | 296 | .compatible = "cfi-flash", |
321 | .data = (void *)"cfi_probe", | 297 | .data = (void *)"cfi_probe", |
@@ -337,30 +313,28 @@ static struct of_device_id of_physmap_match[] = { | |||
337 | }, | 313 | }, |
338 | { }, | 314 | { }, |
339 | }; | 315 | }; |
316 | MODULE_DEVICE_TABLE(of, of_flash_match); | ||
340 | 317 | ||
341 | MODULE_DEVICE_TABLE(of, of_physmap_match); | 318 | static struct of_platform_driver of_flash_driver = { |
342 | 319 | .name = "of-flash", | |
343 | 320 | .match_table = of_flash_match, | |
344 | static struct of_platform_driver of_physmap_flash_driver = { | 321 | .probe = of_flash_probe, |
345 | .name = "physmap-flash", | 322 | .remove = of_flash_remove, |
346 | .match_table = of_physmap_match, | ||
347 | .probe = of_physmap_probe, | ||
348 | .remove = of_physmap_remove, | ||
349 | }; | 323 | }; |
350 | 324 | ||
351 | static int __init of_physmap_init(void) | 325 | static int __init of_flash_init(void) |
352 | { | 326 | { |
353 | return of_register_platform_driver(&of_physmap_flash_driver); | 327 | return of_register_platform_driver(&of_flash_driver); |
354 | } | 328 | } |
355 | 329 | ||
356 | static void __exit of_physmap_exit(void) | 330 | static void __exit of_flash_exit(void) |
357 | { | 331 | { |
358 | of_unregister_platform_driver(&of_physmap_flash_driver); | 332 | of_unregister_platform_driver(&of_flash_driver); |
359 | } | 333 | } |
360 | 334 | ||
361 | module_init(of_physmap_init); | 335 | module_init(of_flash_init); |
362 | module_exit(of_physmap_exit); | 336 | module_exit(of_flash_exit); |
363 | 337 | ||
364 | MODULE_LICENSE("GPL"); | 338 | MODULE_LICENSE("GPL"); |
365 | MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); | 339 | MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); |
366 | MODULE_DESCRIPTION("Configurable MTD map driver for OF"); | 340 | MODULE_DESCRIPTION("Device tree based MTD map driver"); |