Merge git://git.infradead.org/mtd-2.6
[pandora-kernel.git] / drivers / mtd / maps / physmap_of.c
1 /*
2  * Flash mappings described by the OF (or flattened) device tree
3  *
4  * Copyright (C) 2006 MontaVista Software Inc.
5  * Author: Vitaly Wool <vwool@ru.mvista.com>
6  *
7  * Revised to handle newer style flash binding by:
8  *   Copyright (C) 2007 David Gibson, IBM Corporation.
9  *
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>
18 #include <linux/init.h>
19 #include <linux/device.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/partitions.h>
23 #include <linux/mtd/concat.h>
24 #include <linux/of.h>
25 #include <linux/of_platform.h>
26 #include <linux/slab.h>
27
28 struct of_flash_list {
29         struct mtd_info *mtd;
30         struct map_info map;
31         struct resource *res;
32 };
33
34 struct of_flash {
35         struct mtd_info         *cmtd;
36 #ifdef CONFIG_MTD_PARTITIONS
37         struct mtd_partition    *parts;
38 #endif
39         int list_size; /* number of elements in of_flash_list */
40         struct of_flash_list    list[0];
41 };
42
43 #ifdef CONFIG_MTD_PARTITIONS
44 #define OF_FLASH_PARTS(info)    ((info)->parts)
45
46 static int parse_obsolete_partitions(struct of_device *dev,
47                                      struct of_flash *info,
48                                      struct device_node *dp)
49 {
50         int i, plen, nr_parts;
51         const struct {
52                 u32 offset, len;
53         } *part;
54         const char *names;
55
56         part = of_get_property(dp, "partitions", &plen);
57         if (!part)
58                 return 0; /* No partitions found */
59
60         dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n");
61
62         nr_parts = plen / sizeof(part[0]);
63
64         info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL);
65         if (!info->parts)
66                 return -ENOMEM;
67
68         names = of_get_property(dp, "partition-names", &plen);
69
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;
75
76                 if (names && (plen > 0)) {
77                         int len = strlen(names) + 1;
78
79                         info->parts[i].name = (char *)names;
80                         plen -= len;
81                         names += len;
82                 } else {
83                         info->parts[i].name = "unnamed";
84                 }
85
86                 part++;
87         }
88
89         return nr_parts;
90 }
91 #else /* MTD_PARTITIONS */
92 #define OF_FLASH_PARTS(info)            (0)
93 #define parse_partitions(info, dev)     (0)
94 #endif /* MTD_PARTITIONS */
95
96 static int of_flash_remove(struct of_device *dev)
97 {
98         struct of_flash *info;
99         int i;
100
101         info = dev_get_drvdata(&dev->dev);
102         if (!info)
103                 return 0;
104         dev_set_drvdata(&dev->dev, NULL);
105
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) {
114                 if (OF_FLASH_PARTS(info)) {
115                         del_mtd_partitions(info->cmtd);
116                         kfree(OF_FLASH_PARTS(info));
117                 } else {
118                         del_mtd_device(info->cmtd);
119                 }
120         }
121
122         for (i = 0; i < info->list_size; i++) {
123                 if (info->list[i].mtd)
124                         map_destroy(info->list[i].mtd);
125
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                 }
133         }
134
135         kfree(info);
136
137         return 0;
138 }
139
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. */
143 static struct mtd_info * __devinit obsolete_probe(struct of_device *dev,
144                                                   struct map_info *map)
145 {
146         struct device_node *dp = dev->node;
147         const char *of_probe;
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)
170                         dev_warn(&dev->dev, "obsolete_probe: don't know probe "
171                                  "type '%s', mapping as rom\n", of_probe);
172                 return do_map_probe("mtd_rom", map);
173         }
174 }
175
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. */
181 static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", NULL };
182 static 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
211 static void __devinit of_free_probes(const char **probes)
212 {
213         if (probes != part_probe_types_def)
214                 kfree(probes);
215 }
216 #endif
217
218 static int __devinit of_flash_probe(struct of_device *dev,
219                                     const struct of_device_id *match)
220 {
221 #ifdef CONFIG_MTD_PARTITIONS
222         const char **part_probe_types;
223 #endif
224         struct device_node *dp = dev->node;
225         struct resource res;
226         struct of_flash *info;
227         const char *probe_type = match->data;
228         const u32 *width;
229         int err;
230         int i;
231         int count;
232         const u32 *p;
233         int reg_tuple_size;
234         struct mtd_info **mtd_list = NULL;
235         resource_size_t res_size;
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;
250                 goto err_flash_remove;
251         }
252         count /= reg_tuple_size;
253
254         err = -ENOMEM;
255         info = kzalloc(sizeof(struct of_flash) +
256                        sizeof(struct of_flash_list) * count, GFP_KERNEL);
257         if (!info)
258                 goto err_flash_remove;
259
260         dev_set_drvdata(&dev->dev, info);
261
262         mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
263         if (!mtd_list)
264                 goto err_flash_remove;
265
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                 }
273
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;
279                 res_size = resource_size(&res);
280                 info->list[i].res = request_mem_region(res.start, res_size,
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                 }
292
293                 info->list[i].map.name = dev_name(&dev->dev);
294                 info->list[i].map.phys = res.start;
295                 info->list[i].map.size = res_size;
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                 }
306
307                 simple_map_init(&info->list[i].map);
308
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;
317
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         }
328
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
346         }
347         if (err)
348                 goto err_out;
349
350 #ifdef CONFIG_MTD_PARTITIONS
351         part_probe_types = of_get_probes(dp);
352         err = parse_mtd_partitions(info->cmtd, part_probe_types,
353                                    &info->parts, 0);
354         if (err < 0) {
355                 of_free_probes(part_probe_types);
356                 return err;
357         }
358         of_free_probes(part_probe_types);
359
360 #ifdef CONFIG_MTD_OF_PARTS
361         if (err == 0) {
362                 err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
363                 if (err < 0)
364                         return err;
365         }
366 #endif
367
368         if (err == 0) {
369                 err = parse_obsolete_partitions(dev, info, dp);
370                 if (err < 0)
371                         return err;
372         }
373
374         if (err > 0)
375                 add_mtd_partitions(info->cmtd, info->parts, err);
376         else
377 #endif
378                 add_mtd_device(info->cmtd);
379
380         kfree(mtd_list);
381
382         return 0;
383
384 err_out:
385         kfree(mtd_list);
386 err_flash_remove:
387         of_flash_remove(dev);
388
389         return err;
390 }
391
392 static struct of_device_id of_flash_match[] = {
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         },
408         {
409                 .compatible     = "mtd-ram",
410                 .data           = (void *)"map_ram",
411         },
412         {
413                 .type           = "rom",
414                 .compatible     = "direct-mapped"
415         },
416         { },
417 };
418 MODULE_DEVICE_TABLE(of, of_flash_match);
419
420 static 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,
425 };
426
427 static int __init of_flash_init(void)
428 {
429         return of_register_platform_driver(&of_flash_driver);
430 }
431
432 static void __exit of_flash_exit(void)
433 {
434         of_unregister_platform_driver(&of_flash_driver);
435 }
436
437 module_init(of_flash_init);
438 module_exit(of_flash_exit);
439
440 MODULE_LICENSE("GPL");
441 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
442 MODULE_DESCRIPTION("Device tree based MTD map driver");