]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/mtd/maps/physmap_of.c
drivers/mtd/maps: introduce missing kfree
[net-next-2.6.git] / drivers / mtd / maps / physmap_of.c
CommitLineData
a2c2fe4b 1/*
c4d5e375 2 * Flash mappings described by the OF (or flattened) device tree
a2c2fe4b
VW
3 *
4 * Copyright (C) 2006 MontaVista Software Inc.
5 * Author: Vitaly Wool <vwool@ru.mvista.com>
6 *
2099172d
DG
7 * Revised to handle newer style flash binding by:
8 * Copyright (C) 2007 David Gibson, IBM Corporation.
9 *
a2c2fe4b
VW
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/types.h>
a2c2fe4b 18#include <linux/init.h>
a2c2fe4b
VW
19#include <linux/device.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
143070e7 23#include <linux/mtd/concat.h>
c4d5e375
DG
24#include <linux/of.h>
25#include <linux/of_platform.h>
5a0e3ad6 26#include <linux/slab.h>
a2c2fe4b 27
143070e7
SR
28struct of_flash_list {
29 struct mtd_info *mtd;
30 struct map_info map;
31 struct resource *res;
32};
33
c4d5e375 34struct of_flash {
143070e7 35 struct mtd_info *cmtd;
a2c2fe4b 36#ifdef CONFIG_MTD_PARTITIONS
a2c2fe4b
VW
37 struct mtd_partition *parts;
38#endif
143070e7
SR
39 int list_size; /* number of elements in of_flash_list */
40 struct of_flash_list list[0];
a2c2fe4b
VW
41};
42
a2c2fe4b 43#ifdef CONFIG_MTD_PARTITIONS
c4d5e375 44#define OF_FLASH_PARTS(info) ((info)->parts)
a2c2fe4b 45
2099172d 46static int parse_obsolete_partitions(struct of_device *dev,
c4d5e375 47 struct of_flash *info,
2099172d 48 struct device_node *dp)
a2c2fe4b 49{
2099172d
DG
50 int i, plen, nr_parts;
51 const struct {
52 u32 offset, len;
53 } *part;
54 const char *names;
a2c2fe4b 55
2099172d
DG
56 part = of_get_property(dp, "partitions", &plen);
57 if (!part)
c4d5e375 58 return 0; /* No partitions found */
a2c2fe4b 59
2099172d
DG
60 dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
61
62 nr_parts = plen / sizeof(part[0]);
63
c4d5e375
DG
64 info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
65 if (!info->parts)
2099172d 66 return -ENOMEM;
a2c2fe4b 67
2099172d 68 names = of_get_property(dp, "partition-names", &plen);
a2c2fe4b 69
2099172d
DG
70 for (i = 0; i < nr_parts; i++) {
71 info->parts[i].offset = part->offset;
72 info->parts[i].size = part->len & ~1;
73 if (part->len & 1) /* bit 0 set signifies read only partition */
74 info->parts[i].mask_flags = MTD_WRITEABLE;
a2c2fe4b 75
2099172d
DG
76 if (names && (plen > 0)) {
77 int len = strlen(names) + 1;
a2c2fe4b 78
2099172d 79 info->parts[i].name = (char *)names;
a2c2fe4b 80 plen -= len;
2099172d
DG
81 names += len;
82 } else {
83 info->parts[i].name = "unnamed";
84 }
85
86 part++;
a2c2fe4b 87 }
2099172d
DG
88
89 return nr_parts;
a2c2fe4b 90}
2099172d 91#else /* MTD_PARTITIONS */
c4d5e375
DG
92#define OF_FLASH_PARTS(info) (0)
93#define parse_partitions(info, dev) (0)
2099172d 94#endif /* MTD_PARTITIONS */
a2c2fe4b 95
c4d5e375 96static int of_flash_remove(struct of_device *dev)
a2c2fe4b 97{
c4d5e375 98 struct of_flash *info;
143070e7 99 int i;
a2c2fe4b
VW
100
101 info = dev_get_drvdata(&dev->dev);
c4d5e375 102 if (!info)
a2c2fe4b
VW
103 return 0;
104 dev_set_drvdata(&dev->dev, NULL);
105
143070e7
SR
106#ifdef CONFIG_MTD_CONCAT
107 if (info->cmtd != info->list[0].mtd) {
108 del_mtd_device(info->cmtd);
109 mtd_concat_destroy(info->cmtd);
110 }
111#endif
112
113 if (info->cmtd) {
c4d5e375 114 if (OF_FLASH_PARTS(info)) {
143070e7 115 del_mtd_partitions(info->cmtd);
c4d5e375 116 kfree(OF_FLASH_PARTS(info));
a2c2fe4b 117 } else {
143070e7 118 del_mtd_device(info->cmtd);
a2c2fe4b 119 }
a2c2fe4b
VW
120 }
121
143070e7
SR
122 for (i = 0; i < info->list_size; i++) {
123 if (info->list[i].mtd)
124 map_destroy(info->list[i].mtd);
a2c2fe4b 125
143070e7
SR
126 if (info->list[i].map.virt)
127 iounmap(info->list[i].map.virt);
128
129 if (info->list[i].res) {
130 release_resource(info->list[i].res);
131 kfree(info->list[i].res);
132 }
a2c2fe4b
VW
133 }
134
143070e7
SR
135 kfree(info);
136
a2c2fe4b
VW
137 return 0;
138}
139
2099172d
DG
140/* Helper function to handle probing of the obsolete "direct-mapped"
141 * compatible binding, which has an extra "probe-type" property
142 * describing the type of flash probe necessary. */
143static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
144 struct map_info *map)
a2c2fe4b
VW
145{
146 struct device_node *dp = dev->node;
a2c2fe4b 147 const char *of_probe;
2099172d
DG
148 struct mtd_info *mtd;
149 static const char *rom_probe_types[]
150 = { "cfi_probe", "jedec_probe", "map_rom"};
151 int i;
152
153 dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
154 "flash binding\n");
155
156 of_probe = of_get_property(dp, "probe-type", NULL);
157 if (!of_probe) {
158 for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
159 mtd = do_map_probe(rom_probe_types[i], map);
160 if (mtd)
161 return mtd;
162 }
163 return NULL;
164 } else if (strcmp(of_probe, "CFI") == 0) {
165 return do_map_probe("cfi_probe", map);
166 } else if (strcmp(of_probe, "JEDEC") == 0) {
167 return do_map_probe("jedec_probe", map);
168 } else {
169 if (strcmp(of_probe, "ROM") != 0)
c4d5e375
DG
170 dev_warn(&dev->dev, "obsolete_probe: don't know probe "
171 "type '%s', mapping as rom\n", of_probe);
2099172d
DG
172 return do_map_probe("mtd_rom", map);
173 }
174}
175
9d5da3a9
JG
176#ifdef CONFIG_MTD_PARTITIONS
177/* When partitions are set we look for a linux,part-probe property which
178 specifies the list of partition probers to use. If none is given then the
179 default is use. These take precedence over other device tree
180 information. */
181static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
182static const char ** __devinit of_get_probes(struct device_node *dp)
183{
184 const char *cp;
185 int cplen;
186 unsigned int l;
187 unsigned int count;
188 const char **res;
189
190 cp = of_get_property(dp, "linux,part-probe", &cplen);
191 if (cp == NULL)
192 return part_probe_types_def;
193
194 count = 0;
195 for (l = 0; l != cplen; l++)
196 if (cp[l] == 0)
197 count++;
198
199 res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
200 count = 0;
201 while (cplen > 0) {
202 res[count] = cp;
203 l = strlen(cp) + 1;
204 cp += l;
205 cplen -= l;
206 count++;
207 }
208 return res;
209}
210
211static void __devinit of_free_probes(const char **probes)
212{
213 if (probes != part_probe_types_def)
214 kfree(probes);
215}
216#endif
217
c4d5e375
DG
218static int __devinit of_flash_probe(struct of_device *dev,
219 const struct of_device_id *match)
a2c2fe4b 220{
9a310d21 221#ifdef CONFIG_MTD_PARTITIONS
9d5da3a9 222 const char **part_probe_types;
9a310d21 223#endif
a2c2fe4b
VW
224 struct device_node *dp = dev->node;
225 struct resource res;
c4d5e375
DG
226 struct of_flash *info;
227 const char *probe_type = match->data;
a2c2fe4b
VW
228 const u32 *width;
229 int err;
143070e7
SR
230 int i;
231 int count;
232 const u32 *p;
233 int reg_tuple_size;
234 struct mtd_info **mtd_list = NULL;
2763c508 235 resource_size_t res_size;
143070e7
SR
236
237 reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);
238
239 /*
240 * Get number of "reg" tuples. Scan for MTD devices on area's
241 * described by each "reg" region. This makes it possible (including
242 * the concat support) to support the Intel P30 48F4400 chips which
243 * consists internally of 2 non-identical NOR chips on one die.
244 */
245 p = of_get_property(dp, "reg", &count);
246 if (count % reg_tuple_size != 0) {
247 dev_err(&dev->dev, "Malformed reg property on %s\n",
248 dev->node->full_name);
249 err = -EINVAL;
ad4fbc79 250 goto err_flash_remove;
a2c2fe4b 251 }
143070e7 252 count /= reg_tuple_size;
a2c2fe4b 253
c4d5e375 254 err = -ENOMEM;
143070e7
SR
255 info = kzalloc(sizeof(struct of_flash) +
256 sizeof(struct of_flash_list) * count, GFP_KERNEL);
257 if (!info)
ad4fbc79 258 goto err_flash_remove;
a2c2fe4b
VW
259
260 dev_set_drvdata(&dev->dev, info);
261
e026255f 262 mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
ad4fbc79 263 if (!mtd_list)
264 goto err_flash_remove;
265
143070e7
SR
266 for (i = 0; i < count; i++) {
267 err = -ENXIO;
268 if (of_address_to_resource(dp, i, &res)) {
269 dev_err(&dev->dev, "Can't get IO address from device"
270 " tree\n");
271 goto err_out;
272 }
a2c2fe4b 273
143070e7
SR
274 dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n",
275 (unsigned long long)res.start,
276 (unsigned long long)res.end);
277
278 err = -EBUSY;
2763c508
WS
279 res_size = resource_size(&res);
280 info->list[i].res = request_mem_region(res.start, res_size,
143070e7
SR
281 dev_name(&dev->dev));
282 if (!info->list[i].res)
283 goto err_out;
284
285 err = -ENXIO;
286 width = of_get_property(dp, "bank-width", NULL);
287 if (!width) {
288 dev_err(&dev->dev, "Can't get bank width from device"
289 " tree\n");
290 goto err_out;
291 }
a2c2fe4b 292
143070e7
SR
293 info->list[i].map.name = dev_name(&dev->dev);
294 info->list[i].map.phys = res.start;
2763c508 295 info->list[i].map.size = res_size;
143070e7
SR
296 info->list[i].map.bankwidth = *width;
297
298 err = -ENOMEM;
299 info->list[i].map.virt = ioremap(info->list[i].map.phys,
300 info->list[i].map.size);
301 if (!info->list[i].map.virt) {
302 dev_err(&dev->dev, "Failed to ioremap() flash"
303 " region\n");
304 goto err_out;
305 }
a2c2fe4b 306
143070e7 307 simple_map_init(&info->list[i].map);
a2c2fe4b 308
143070e7
SR
309 if (probe_type) {
310 info->list[i].mtd = do_map_probe(probe_type,
311 &info->list[i].map);
312 } else {
313 info->list[i].mtd = obsolete_probe(dev,
314 &info->list[i].map);
315 }
316 mtd_list[i] = info->list[i].mtd;
a2c2fe4b 317
143070e7
SR
318 err = -ENXIO;
319 if (!info->list[i].mtd) {
320 dev_err(&dev->dev, "do_map_probe() failed\n");
321 goto err_out;
322 } else {
323 info->list_size++;
324 }
325 info->list[i].mtd->owner = THIS_MODULE;
326 info->list[i].mtd->dev.parent = &dev->dev;
327 }
2099172d 328
143070e7
SR
329 err = 0;
330 if (info->list_size == 1) {
331 info->cmtd = info->list[0].mtd;
332 } else if (info->list_size > 1) {
333 /*
334 * We detected multiple devices. Concatenate them together.
335 */
336#ifdef CONFIG_MTD_CONCAT
337 info->cmtd = mtd_concat_create(mtd_list, info->list_size,
338 dev_name(&dev->dev));
339 if (info->cmtd == NULL)
340 err = -ENXIO;
341#else
342 printk(KERN_ERR "physmap_of: multiple devices "
343 "found but MTD concat support disabled.\n");
344 err = -ENXIO;
345#endif
a2c2fe4b 346 }
143070e7
SR
347 if (err)
348 goto err_out;
a2c2fe4b 349
9a310d21 350#ifdef CONFIG_MTD_PARTITIONS
9d5da3a9 351 part_probe_types = of_get_probes(dp);
143070e7
SR
352 err = parse_mtd_partitions(info->cmtd, part_probe_types,
353 &info->parts, 0);
9d5da3a9
JG
354 if (err < 0) {
355 of_free_probes(part_probe_types);
00b275db 356 goto err_out;
9d5da3a9
JG
357 }
358 of_free_probes(part_probe_types);
9a310d21
SW
359
360#ifdef CONFIG_MTD_OF_PARTS
361 if (err == 0) {
69fd3a8d 362 err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
9a310d21 363 if (err < 0)
00b275db 364 goto err_out;
9a310d21
SW
365 }
366#endif
367
368 if (err == 0) {
369 err = parse_obsolete_partitions(dev, info, dp);
370 if (err < 0)
00b275db 371 goto err_out;
9a310d21 372 }
a2c2fe4b 373
c4d5e375 374 if (err > 0)
143070e7 375 add_mtd_partitions(info->cmtd, info->parts, err);
c4d5e375 376 else
9a310d21 377#endif
143070e7
SR
378 add_mtd_device(info->cmtd);
379
380 kfree(mtd_list);
a2c2fe4b 381
a2c2fe4b
VW
382 return 0;
383
384err_out:
143070e7 385 kfree(mtd_list);
ad4fbc79 386err_flash_remove:
c4d5e375 387 of_flash_remove(dev);
143070e7 388
a2c2fe4b 389 return err;
a2c2fe4b
VW
390}
391
c4d5e375 392static struct of_device_id of_flash_match[] = {
2099172d
DG
393 {
394 .compatible = "cfi-flash",
395 .data = (void *)"cfi_probe",
396 },
397 {
398 /* FIXME: JEDEC chips can't be safely and reliably
399 * probed, although the mtd code gets it right in
400 * practice most of the time. We should use the
401 * vendor and device ids specified by the binding to
402 * bypass the heuristic probe code, but the mtd layer
403 * provides, at present, no interface for doing so
404 * :(. */
405 .compatible = "jedec-flash",
406 .data = (void *)"jedec_probe",
407 },
fc28c39f
WS
408 {
409 .compatible = "mtd-ram",
410 .data = (void *)"map_ram",
411 },
a2c2fe4b
VW
412 {
413 .type = "rom",
414 .compatible = "direct-mapped"
415 },
416 { },
417};
c4d5e375 418MODULE_DEVICE_TABLE(of, of_flash_match);
a2c2fe4b 419
c4d5e375
DG
420static struct of_platform_driver of_flash_driver = {
421 .name = "of-flash",
422 .match_table = of_flash_match,
423 .probe = of_flash_probe,
424 .remove = of_flash_remove,
a2c2fe4b
VW
425};
426
c4d5e375 427static int __init of_flash_init(void)
a2c2fe4b 428{
c4d5e375 429 return of_register_platform_driver(&of_flash_driver);
a2c2fe4b
VW
430}
431
c4d5e375 432static void __exit of_flash_exit(void)
a2c2fe4b 433{
c4d5e375 434 of_unregister_platform_driver(&of_flash_driver);
a2c2fe4b
VW
435}
436
c4d5e375
DG
437module_init(of_flash_init);
438module_exit(of_flash_exit);
a2c2fe4b
VW
439
440MODULE_LICENSE("GPL");
441MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
c4d5e375 442MODULE_DESCRIPTION("Device tree based MTD map driver");