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