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