aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-09-19 21:22:25 -0400
committerJosh Boyer <jwboyer@linux.vnet.ibm.com>2007-09-20 08:37:16 -0400
commitc4d5e375470862fd741f93bf0686d7ac2f7fdce4 (patch)
tree8a82ce5fadde3c8a752f1080b427ef3c4c45e3d7 /drivers/mtd
parentbd0076cc330f303905018a17d9dcfbabde497572 (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.c224
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
31struct physmap_flash_info { 26struct 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
41static int parse_obsolete_partitions(struct of_device *dev, 38static 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
89static int __devinit process_partitions(struct physmap_flash_info *info, 84static 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 */
160static 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
168static int of_physmap_remove(struct of_device *dev) 146static 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
238static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) 212static 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
309err_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 289err_out:
290 of_flash_remove(dev);
291 return err;
316} 292}
317 293
318static struct of_device_id of_physmap_match[] = { 294static 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};
316MODULE_DEVICE_TABLE(of, of_flash_match);
340 317
341MODULE_DEVICE_TABLE(of, of_physmap_match); 318static struct of_platform_driver of_flash_driver = {
342 319 .name = "of-flash",
343 320 .match_table = of_flash_match,
344static 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
351static int __init of_physmap_init(void) 325static 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
356static void __exit of_physmap_exit(void) 330static 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
361module_init(of_physmap_init); 335module_init(of_flash_init);
362module_exit(of_physmap_exit); 336module_exit(of_flash_exit);
363 337
364MODULE_LICENSE("GPL"); 338MODULE_LICENSE("GPL");
365MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); 339MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
366MODULE_DESCRIPTION("Configurable MTD map driver for OF"); 340MODULE_DESCRIPTION("Device tree based MTD map driver");