Merge branch 'sfc-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc
[deliverable/linux.git] / drivers / mtd / maps / physmap_of.c
CommitLineData
a2c2fe4b 1/*
c4d5e375 2 * Flash mappings described by the OF (or flattened) device tree
a2c2fe4b
VW
3 *
4 * Copyright (C) 2006 MontaVista Software Inc.
5 * Author: Vitaly Wool <vwool@ru.mvista.com>
6 *
2099172d
DG
7 * Revised to handle newer style flash binding by:
8 * Copyright (C) 2007 David Gibson, IBM Corporation.
9 *
a2c2fe4b
VW
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>
a2c2fe4b 18#include <linux/init.h>
a2c2fe4b
VW
19#include <linux/device.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
143070e7 23#include <linux/mtd/concat.h>
c4d5e375 24#include <linux/of.h>
7a50d06e 25#include <linux/of_address.h>
c4d5e375 26#include <linux/of_platform.h>
5a0e3ad6 27#include <linux/slab.h>
a2c2fe4b 28
143070e7
SR
29struct of_flash_list {
30 struct mtd_info *mtd;
31 struct map_info map;
32 struct resource *res;
33};
34
c4d5e375 35struct of_flash {
143070e7 36 struct mtd_info *cmtd;
143070e7
SR
37 int list_size; /* number of elements in of_flash_list */
38 struct of_flash_list list[0];
a2c2fe4b
VW
39};
40
2dc11581 41static int of_flash_remove(struct platform_device *dev)
a2c2fe4b 42{
c4d5e375 43 struct of_flash *info;
143070e7 44 int i;
a2c2fe4b
VW
45
46 info = dev_get_drvdata(&dev->dev);
c4d5e375 47 if (!info)
a2c2fe4b
VW
48 return 0;
49 dev_set_drvdata(&dev->dev, NULL);
50
143070e7 51 if (info->cmtd != info->list[0].mtd) {
984e6d8e 52 mtd_device_unregister(info->cmtd);
143070e7
SR
53 mtd_concat_destroy(info->cmtd);
54 }
143070e7 55
f44dcbd0 56 if (info->cmtd)
984e6d8e 57 mtd_device_unregister(info->cmtd);
a2c2fe4b 58
143070e7
SR
59 for (i = 0; i < info->list_size; i++) {
60 if (info->list[i].mtd)
61 map_destroy(info->list[i].mtd);
a2c2fe4b 62
143070e7
SR
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 }
a2c2fe4b 70 }
a2c2fe4b
VW
71 return 0;
72}
73
2099172d
DG
74/* Helper function to handle probing of the obsolete "direct-mapped"
75 * compatible binding, which has an extra "probe-type" property
76 * describing the type of flash probe necessary. */
06f25510 77static struct mtd_info *obsolete_probe(struct platform_device *dev,
d8929942 78 struct map_info *map)
a2c2fe4b 79{
61c7a080 80 struct device_node *dp = dev->dev.of_node;
a2c2fe4b 81 const char *of_probe;
2099172d
DG
82 struct mtd_info *mtd;
83 static const char *rom_probe_types[]
84 = { "cfi_probe", "jedec_probe", "map_rom"};
85 int i;
86
87 dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
88 "flash binding\n");
89
90 of_probe = of_get_property(dp, "probe-type", NULL);
91 if (!of_probe) {
92 for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
93 mtd = do_map_probe(rom_probe_types[i], map);
94 if (mtd)
95 return mtd;
96 }
97 return NULL;
98 } else if (strcmp(of_probe, "CFI") == 0) {
99 return do_map_probe("cfi_probe", map);
100 } else if (strcmp(of_probe, "JEDEC") == 0) {
101 return do_map_probe("jedec_probe", map);
102 } else {
103 if (strcmp(of_probe, "ROM") != 0)
c4d5e375
DG
104 dev_warn(&dev->dev, "obsolete_probe: don't know probe "
105 "type '%s', mapping as rom\n", of_probe);
2099172d
DG
106 return do_map_probe("mtd_rom", map);
107 }
108}
109
9d5da3a9
JG
110/* When partitions are set we look for a linux,part-probe property which
111 specifies the list of partition probers to use. If none is given then the
112 default is use. These take precedence over other device tree
113 information. */
5f4ba9f9 114static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
fbcf62a3 115 "ofpart", "ofoldpart", NULL };
06f25510 116static const char **of_get_probes(struct device_node *dp)
9d5da3a9
JG
117{
118 const char *cp;
119 int cplen;
120 unsigned int l;
121 unsigned int count;
122 const char **res;
123
124 cp = of_get_property(dp, "linux,part-probe", &cplen);
125 if (cp == NULL)
126 return part_probe_types_def;
127
128 count = 0;
129 for (l = 0; l != cplen; l++)
130 if (cp[l] == 0)
131 count++;
132
133 res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
134 count = 0;
135 while (cplen > 0) {
136 res[count] = cp;
137 l = strlen(cp) + 1;
138 cp += l;
139 cplen -= l;
140 count++;
141 }
142 return res;
143}
144
06f25510 145static void of_free_probes(const char **probes)
9d5da3a9
JG
146{
147 if (probes != part_probe_types_def)
148 kfree(probes);
149}
9d5da3a9 150
b1608d69 151static struct of_device_id of_flash_match[];
06f25510 152static int of_flash_probe(struct platform_device *dev)
a2c2fe4b 153{
9d5da3a9 154 const char **part_probe_types;
b1608d69 155 const struct of_device_id *match;
61c7a080 156 struct device_node *dp = dev->dev.of_node;
a2c2fe4b 157 struct resource res;
c4d5e375 158 struct of_flash *info;
1c48a5c9 159 const char *probe_type;
766f271a 160 const __be32 *width;
a2c2fe4b 161 int err;
143070e7
SR
162 int i;
163 int count;
766f271a 164 const __be32 *p;
143070e7
SR
165 int reg_tuple_size;
166 struct mtd_info **mtd_list = NULL;
2763c508 167 resource_size_t res_size;
5f4ba9f9 168 struct mtd_part_parser_data ppdata;
d0788ce4 169 bool map_indirect;
7dfe4be3 170 const char *mtd_name = NULL;
143070e7 171
b1608d69
GL
172 match = of_match_device(of_flash_match, &dev->dev);
173 if (!match)
1c48a5c9 174 return -EINVAL;
b1608d69 175 probe_type = match->data;
1c48a5c9 176
143070e7
SR
177 reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32);
178
d68cbdd4
JCPV
179 of_property_read_string(dp, "linux,mtd-name", &mtd_name);
180
143070e7
SR
181 /*
182 * Get number of "reg" tuples. Scan for MTD devices on area's
183 * described by each "reg" region. This makes it possible (including
184 * the concat support) to support the Intel P30 48F4400 chips which
185 * consists internally of 2 non-identical NOR chips on one die.
186 */
187 p = of_get_property(dp, "reg", &count);
188 if (count % reg_tuple_size != 0) {
189 dev_err(&dev->dev, "Malformed reg property on %s\n",
61c7a080 190 dev->dev.of_node->full_name);
143070e7 191 err = -EINVAL;
ad4fbc79 192 goto err_flash_remove;
a2c2fe4b 193 }
143070e7 194 count /= reg_tuple_size;
a2c2fe4b 195
d0788ce4
SR
196 map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access");
197
c4d5e375 198 err = -ENOMEM;
eb82038f
EG
199 info = devm_kzalloc(&dev->dev,
200 sizeof(struct of_flash) +
201 sizeof(struct of_flash_list) * count, GFP_KERNEL);
143070e7 202 if (!info)
ad4fbc79 203 goto err_flash_remove;
a2c2fe4b
VW
204
205 dev_set_drvdata(&dev->dev, info);
206
e026255f 207 mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
ad4fbc79 208 if (!mtd_list)
209 goto err_flash_remove;
210
143070e7
SR
211 for (i = 0; i < count; i++) {
212 err = -ENXIO;
213 if (of_address_to_resource(dp, i, &res)) {
940fe282
SR
214 /*
215 * Continue with next register tuple if this
216 * one is not mappable
217 */
218 continue;
143070e7 219 }
a2c2fe4b 220
f9a5279c 221 dev_dbg(&dev->dev, "of_flash device: %pR\n", &res);
143070e7
SR
222
223 err = -EBUSY;
2763c508
WS
224 res_size = resource_size(&res);
225 info->list[i].res = request_mem_region(res.start, res_size,
143070e7
SR
226 dev_name(&dev->dev));
227 if (!info->list[i].res)
228 goto err_out;
229
230 err = -ENXIO;
231 width = of_get_property(dp, "bank-width", NULL);
232 if (!width) {
233 dev_err(&dev->dev, "Can't get bank width from device"
234 " tree\n");
235 goto err_out;
236 }
a2c2fe4b 237
d68cbdd4 238 info->list[i].map.name = mtd_name ?: dev_name(&dev->dev);
143070e7 239 info->list[i].map.phys = res.start;
2763c508 240 info->list[i].map.size = res_size;
766f271a 241 info->list[i].map.bankwidth = be32_to_cpup(width);
1648eaaa 242 info->list[i].map.device_node = dp;
143070e7
SR
243
244 err = -ENOMEM;
245 info->list[i].map.virt = ioremap(info->list[i].map.phys,
246 info->list[i].map.size);
247 if (!info->list[i].map.virt) {
248 dev_err(&dev->dev, "Failed to ioremap() flash"
249 " region\n");
250 goto err_out;
251 }
a2c2fe4b 252
143070e7 253 simple_map_init(&info->list[i].map);
a2c2fe4b 254
d0788ce4
SR
255 /*
256 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
257 * may cause problems with JFFS2 usage, as the local bus (LPB)
258 * doesn't support unaligned accesses as implemented in the
259 * JFFS2 code via memcpy(). By setting NO_XIP, the
260 * flash will not be exposed directly to the MTD users
261 * (e.g. JFFS2) any more.
262 */
263 if (map_indirect)
264 info->list[i].map.phys = NO_XIP;
265
143070e7
SR
266 if (probe_type) {
267 info->list[i].mtd = do_map_probe(probe_type,
268 &info->list[i].map);
269 } else {
270 info->list[i].mtd = obsolete_probe(dev,
271 &info->list[i].map);
272 }
273 mtd_list[i] = info->list[i].mtd;
a2c2fe4b 274
143070e7
SR
275 err = -ENXIO;
276 if (!info->list[i].mtd) {
277 dev_err(&dev->dev, "do_map_probe() failed\n");
278 goto err_out;
279 } else {
280 info->list_size++;
281 }
282 info->list[i].mtd->owner = THIS_MODULE;
283 info->list[i].mtd->dev.parent = &dev->dev;
284 }
2099172d 285
143070e7 286 err = 0;
e58a66d8 287 info->cmtd = NULL;
143070e7
SR
288 if (info->list_size == 1) {
289 info->cmtd = info->list[0].mtd;
290 } else if (info->list_size > 1) {
291 /*
292 * We detected multiple devices. Concatenate them together.
293 */
143070e7
SR
294 info->cmtd = mtd_concat_create(mtd_list, info->list_size,
295 dev_name(&dev->dev));
a2c2fe4b 296 }
e58a66d8
AP
297 if (info->cmtd == NULL)
298 err = -ENXIO;
299
143070e7
SR
300 if (err)
301 goto err_out;
a2c2fe4b 302
5f4ba9f9 303 ppdata.of_node = dp;
9d5da3a9 304 part_probe_types = of_get_probes(dp);
f44dcbd0
DES
305 mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
306 NULL, 0);
9d5da3a9 307 of_free_probes(part_probe_types);
9a310d21 308
143070e7 309 kfree(mtd_list);
a2c2fe4b 310
a2c2fe4b
VW
311 return 0;
312
313err_out:
143070e7 314 kfree(mtd_list);
ad4fbc79 315err_flash_remove:
c4d5e375 316 of_flash_remove(dev);
143070e7 317
a2c2fe4b 318 return err;
a2c2fe4b
VW
319}
320
c4d5e375 321static struct of_device_id of_flash_match[] = {
2099172d
DG
322 {
323 .compatible = "cfi-flash",
324 .data = (void *)"cfi_probe",
325 },
326 {
327 /* FIXME: JEDEC chips can't be safely and reliably
328 * probed, although the mtd code gets it right in
329 * practice most of the time. We should use the
330 * vendor and device ids specified by the binding to
331 * bypass the heuristic probe code, but the mtd layer
332 * provides, at present, no interface for doing so
333 * :(. */
334 .compatible = "jedec-flash",
335 .data = (void *)"jedec_probe",
336 },
fc28c39f
WS
337 {
338 .compatible = "mtd-ram",
339 .data = (void *)"map_ram",
340 },
a2c2fe4b
VW
341 {
342 .type = "rom",
343 .compatible = "direct-mapped"
344 },
345 { },
346};
c4d5e375 347MODULE_DEVICE_TABLE(of, of_flash_match);
a2c2fe4b 348
1c48a5c9 349static struct platform_driver of_flash_driver = {
4018294b
GL
350 .driver = {
351 .name = "of-flash",
352 .owner = THIS_MODULE,
353 .of_match_table = of_flash_match,
354 },
c4d5e375
DG
355 .probe = of_flash_probe,
356 .remove = of_flash_remove,
a2c2fe4b
VW
357};
358
f99640de 359module_platform_driver(of_flash_driver);
a2c2fe4b
VW
360
361MODULE_LICENSE("GPL");
362MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
c4d5e375 363MODULE_DESCRIPTION("Device tree based MTD map driver");
This page took 0.417238 seconds and 5 git commands to generate.