Merge branch 'ib-chrome-platform-atmel-mxt-ts-device-properties' of git://git.kernel...
[linux-2.6-microblaze.git] / drivers / mtd / maps / physmap_of_core.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/device.h>
19 #include <linux/mtd/mtd.h>
20 #include <linux/mtd/map.h>
21 #include <linux/mtd/partitions.h>
22 #include <linux/mtd/concat.h>
23 #include <linux/mtd/cfi_endian.h>
24 #include <linux/of.h>
25 #include <linux/of_address.h>
26 #include <linux/of_platform.h>
27 #include <linux/slab.h>
28 #include "physmap_of_gemini.h"
29 #include "physmap_of_versatile.h"
30
31 struct of_flash_list {
32         struct mtd_info *mtd;
33         struct map_info map;
34         struct resource *res;
35 };
36
37 struct of_flash {
38         struct mtd_info         *cmtd;
39         int list_size; /* number of elements in of_flash_list */
40         struct of_flash_list    list[0];
41 };
42
43 static int of_flash_remove(struct platform_device *dev)
44 {
45         struct of_flash *info;
46         int i;
47
48         info = dev_get_drvdata(&dev->dev);
49         if (!info)
50                 return 0;
51         dev_set_drvdata(&dev->dev, NULL);
52
53         if (info->cmtd) {
54                 mtd_device_unregister(info->cmtd);
55                 if (info->cmtd != info->list[0].mtd)
56                         mtd_concat_destroy(info->cmtd);
57         }
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         return 0;
72 }
73
74 static const char * const rom_probe_types[] = {
75         "cfi_probe", "jedec_probe", "map_rom" };
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 *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         int i;
87
88         dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
89                  "flash binding\n");
90
91         of_probe = of_get_property(dp, "probe-type", NULL);
92         if (!of_probe) {
93                 for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
94                         mtd = do_map_probe(rom_probe_types[i], map);
95                         if (mtd)
96                                 return mtd;
97                 }
98                 return NULL;
99         } else if (strcmp(of_probe, "CFI") == 0) {
100                 return do_map_probe("cfi_probe", map);
101         } else if (strcmp(of_probe, "JEDEC") == 0) {
102                 return do_map_probe("jedec_probe", map);
103         } else {
104                 if (strcmp(of_probe, "ROM") != 0)
105                         dev_warn(&dev->dev, "obsolete_probe: don't know probe "
106                                  "type '%s', mapping as rom\n", of_probe);
107                 return do_map_probe("map_rom", map);
108         }
109 }
110
111 /* When partitions are set we look for a linux,part-probe property which
112    specifies the list of partition probers to use. If none is given then the
113    default is use. These take precedence over other device tree
114    information. */
115 static const char * const part_probe_types_def[] = {
116         "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
117
118 static const char * const *of_get_probes(struct device_node *dp)
119 {
120         const char **res;
121         int count;
122
123         count = of_property_count_strings(dp, "linux,part-probe");
124         if (count < 0)
125                 return part_probe_types_def;
126
127         res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL);
128         if (!res)
129                 return NULL;
130
131         count = of_property_read_string_array(dp, "linux,part-probe", res,
132                                               count);
133         if (count < 0)
134                 return NULL;
135
136         return res;
137 }
138
139 static void of_free_probes(const char * const *probes)
140 {
141         if (probes != part_probe_types_def)
142                 kfree(probes);
143 }
144
145 static const struct of_device_id of_flash_match[];
146 static int of_flash_probe(struct platform_device *dev)
147 {
148         const char * const *part_probe_types;
149         const struct of_device_id *match;
150         struct device_node *dp = dev->dev.of_node;
151         struct resource res;
152         struct of_flash *info;
153         const char *probe_type;
154         const __be32 *width;
155         int err;
156         int i;
157         int count;
158         const __be32 *p;
159         int reg_tuple_size;
160         struct mtd_info **mtd_list = NULL;
161         resource_size_t res_size;
162         bool map_indirect;
163         const char *mtd_name = NULL;
164
165         match = of_match_device(of_flash_match, &dev->dev);
166         if (!match)
167                 return -EINVAL;
168         probe_type = match->data;
169
170         reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);
171
172         of_property_read_string(dp, "linux,mtd-name", &mtd_name);
173
174         /*
175          * Get number of "reg" tuples. Scan for MTD devices on area's
176          * described by each "reg" region. This makes it possible (including
177          * the concat support) to support the Intel P30 48F4400 chips which
178          * consists internally of 2 non-identical NOR chips on one die.
179          */
180         p = of_get_property(dp, "reg", &count);
181         if (!p || count % reg_tuple_size != 0) {
182                 dev_err(&dev->dev, "Malformed reg property on %pOF\n",
183                                 dev->dev.of_node);
184                 err = -EINVAL;
185                 goto err_flash_remove;
186         }
187         count /= reg_tuple_size;
188
189         map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access");
190
191         err = -ENOMEM;
192         info = devm_kzalloc(&dev->dev,
193                             sizeof(struct of_flash) +
194                             sizeof(struct of_flash_list) * count, GFP_KERNEL);
195         if (!info)
196                 goto err_flash_remove;
197
198         dev_set_drvdata(&dev->dev, info);
199
200         mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
201         if (!mtd_list)
202                 goto err_flash_remove;
203
204         for (i = 0; i < count; i++) {
205                 err = -ENXIO;
206                 if (of_address_to_resource(dp, i, &res)) {
207                         /*
208                          * Continue with next register tuple if this
209                          * one is not mappable
210                          */
211                         continue;
212                 }
213
214                 dev_dbg(&dev->dev, "of_flash device: %pR\n", &res);
215
216                 err = -EBUSY;
217                 res_size = resource_size(&res);
218                 info->list[i].res = request_mem_region(res.start, res_size,
219                                                        dev_name(&dev->dev));
220                 if (!info->list[i].res)
221                         goto err_out;
222
223                 err = -ENXIO;
224                 width = of_get_property(dp, "bank-width", NULL);
225                 if (!width) {
226                         dev_err(&dev->dev, "Can't get bank width from device"
227                                 " tree\n");
228                         goto err_out;
229                 }
230
231                 info->list[i].map.name = mtd_name ?: dev_name(&dev->dev);
232                 info->list[i].map.phys = res.start;
233                 info->list[i].map.size = res_size;
234                 info->list[i].map.bankwidth = be32_to_cpup(width);
235                 info->list[i].map.device_node = dp;
236
237                 if (of_property_read_bool(dp, "big-endian"))
238                         info->list[i].map.swap = CFI_BIG_ENDIAN;
239                 else if (of_property_read_bool(dp, "little-endian"))
240                         info->list[i].map.swap = CFI_LITTLE_ENDIAN;
241
242                 err = of_flash_probe_gemini(dev, dp, &info->list[i].map);
243                 if (err)
244                         goto err_out;
245                 err = of_flash_probe_versatile(dev, dp, &info->list[i].map);
246                 if (err)
247                         goto err_out;
248
249                 err = -ENOMEM;
250                 info->list[i].map.virt = ioremap(info->list[i].map.phys,
251                                                  info->list[i].map.size);
252                 if (!info->list[i].map.virt) {
253                         dev_err(&dev->dev, "Failed to ioremap() flash"
254                                 " region\n");
255                         goto err_out;
256                 }
257
258                 simple_map_init(&info->list[i].map);
259
260                 /*
261                  * On some platforms (e.g. MPC5200) a direct 1:1 mapping
262                  * may cause problems with JFFS2 usage, as the local bus (LPB)
263                  * doesn't support unaligned accesses as implemented in the
264                  * JFFS2 code via memcpy(). By setting NO_XIP, the
265                  * flash will not be exposed directly to the MTD users
266                  * (e.g. JFFS2) any more.
267                  */
268                 if (map_indirect)
269                         info->list[i].map.phys = NO_XIP;
270
271                 if (probe_type) {
272                         info->list[i].mtd = do_map_probe(probe_type,
273                                                          &info->list[i].map);
274                 } else {
275                         info->list[i].mtd = obsolete_probe(dev,
276                                                            &info->list[i].map);
277                 }
278
279                 /* Fall back to mapping region as ROM */
280                 if (!info->list[i].mtd) {
281                         dev_warn(&dev->dev,
282                                 "do_map_probe() failed for type %s\n",
283                                  probe_type);
284
285                         info->list[i].mtd = do_map_probe("map_rom",
286                                                          &info->list[i].map);
287                 }
288                 mtd_list[i] = info->list[i].mtd;
289
290                 err = -ENXIO;
291                 if (!info->list[i].mtd) {
292                         dev_err(&dev->dev, "do_map_probe() failed\n");
293                         goto err_out;
294                 } else {
295                         info->list_size++;
296                 }
297                 info->list[i].mtd->dev.parent = &dev->dev;
298         }
299
300         err = 0;
301         info->cmtd = NULL;
302         if (info->list_size == 1) {
303                 info->cmtd = info->list[0].mtd;
304         } else if (info->list_size > 1) {
305                 /*
306                  * We detected multiple devices. Concatenate them together.
307                  */
308                 info->cmtd = mtd_concat_create(mtd_list, info->list_size,
309                                                dev_name(&dev->dev));
310         }
311         if (info->cmtd == NULL)
312                 err = -ENXIO;
313
314         if (err)
315                 goto err_out;
316
317         info->cmtd->dev.parent = &dev->dev;
318         mtd_set_of_node(info->cmtd, dp);
319         part_probe_types = of_get_probes(dp);
320         if (!part_probe_types) {
321                 err = -ENOMEM;
322                 goto err_out;
323         }
324         mtd_device_parse_register(info->cmtd, part_probe_types, NULL,
325                         NULL, 0);
326         of_free_probes(part_probe_types);
327
328         kfree(mtd_list);
329
330         return 0;
331
332 err_out:
333         kfree(mtd_list);
334 err_flash_remove:
335         of_flash_remove(dev);
336
337         return err;
338 }
339
340 static const struct of_device_id of_flash_match[] = {
341         {
342                 .compatible     = "cfi-flash",
343                 .data           = (void *)"cfi_probe",
344         },
345         {
346                 /* FIXME: JEDEC chips can't be safely and reliably
347                  * probed, although the mtd code gets it right in
348                  * practice most of the time.  We should use the
349                  * vendor and device ids specified by the binding to
350                  * bypass the heuristic probe code, but the mtd layer
351                  * provides, at present, no interface for doing so
352                  * :(. */
353                 .compatible     = "jedec-flash",
354                 .data           = (void *)"jedec_probe",
355         },
356         {
357                 .compatible     = "mtd-ram",
358                 .data           = (void *)"map_ram",
359         },
360         {
361                 .compatible     = "mtd-rom",
362                 .data           = (void *)"map_rom",
363         },
364         {
365                 .type           = "rom",
366                 .compatible     = "direct-mapped"
367         },
368         { },
369 };
370 MODULE_DEVICE_TABLE(of, of_flash_match);
371
372 static struct platform_driver of_flash_driver = {
373         .driver = {
374                 .name = "of-flash",
375                 .of_match_table = of_flash_match,
376         },
377         .probe          = of_flash_probe,
378         .remove         = of_flash_remove,
379 };
380
381 module_platform_driver(of_flash_driver);
382
383 MODULE_LICENSE("GPL");
384 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
385 MODULE_DESCRIPTION("Device tree based MTD map driver");