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