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