mtd: ofpart: drop 'of_node' partition parser data
[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
VW
18#include <linux/device.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/map.h>
21#include <linux/mtd/partitions.h>
143070e7 22#include <linux/mtd/concat.h>
c4d5e375 23#include <linux/of.h>
7a50d06e 24#include <linux/of_address.h>
c4d5e375 25#include <linux/of_platform.h>
5a0e3ad6 26#include <linux/slab.h>
a2c2fe4b 27
143070e7
SR
28struct of_flash_list {
29 struct mtd_info *mtd;
30 struct map_info map;
31 struct resource *res;
32};
33
c4d5e375 34struct of_flash {
143070e7 35 struct mtd_info *cmtd;
143070e7
SR
36 int list_size; /* number of elements in of_flash_list */
37 struct of_flash_list list[0];
a2c2fe4b
VW
38};
39
2dc11581 40static int of_flash_remove(struct platform_device *dev)
a2c2fe4b 41{
c4d5e375 42 struct of_flash *info;
143070e7 43 int i;
a2c2fe4b
VW
44
45 info = dev_get_drvdata(&dev->dev);
c4d5e375 46 if (!info)
a2c2fe4b
VW
47 return 0;
48 dev_set_drvdata(&dev->dev, NULL);
49
92b633a8 50 if (info->cmtd) {
984e6d8e 51 mtd_device_unregister(info->cmtd);
92b633a8
AB
52 if (info->cmtd != info->list[0].mtd)
53 mtd_concat_destroy(info->cmtd);
143070e7 54 }
143070e7 55
143070e7
SR
56 for (i = 0; i < info->list_size; i++) {
57 if (info->list[i].mtd)
58 map_destroy(info->list[i].mtd);
a2c2fe4b 59
143070e7
SR
60 if (info->list[i].map.virt)
61 iounmap(info->list[i].map.virt);
62
63 if (info->list[i].res) {
64 release_resource(info->list[i].res);
65 kfree(info->list[i].res);
66 }
a2c2fe4b 67 }
a2c2fe4b
VW
68 return 0;
69}
70
cce2a026
AB
71static const char * const rom_probe_types[] = {
72 "cfi_probe", "jedec_probe", "map_rom" };
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 82 struct mtd_info *mtd;
2099172d
DG
83 int i;
84
85 dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
86 "flash binding\n");
87
88 of_probe = of_get_property(dp, "probe-type", NULL);
89 if (!of_probe) {
90 for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
91 mtd = do_map_probe(rom_probe_types[i], map);
92 if (mtd)
93 return mtd;
94 }
95 return NULL;
96 } else if (strcmp(of_probe, "CFI") == 0) {
97 return do_map_probe("cfi_probe", map);
98 } else if (strcmp(of_probe, "JEDEC") == 0) {
99 return do_map_probe("jedec_probe", map);
100 } else {
101 if (strcmp(of_probe, "ROM") != 0)
c4d5e375
DG
102 dev_warn(&dev->dev, "obsolete_probe: don't know probe "
103 "type '%s', mapping as rom\n", of_probe);
9b07a8d1 104 return do_map_probe("map_rom", map);
2099172d
DG
105 }
106}
107
9d5da3a9
JG
108/* When partitions are set we look for a linux,part-probe property which
109 specifies the list of partition probers to use. If none is given then the
110 default is use. These take precedence over other device tree
111 information. */
cce2a026
AB
112static const char * const part_probe_types_def[] = {
113 "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL };
114
115static const char * const *of_get_probes(struct device_node *dp)
9d5da3a9
JG
116{
117 const char *cp;
118 int cplen;
119 unsigned int l;
120 unsigned int count;
121 const char **res;
122
123 cp = of_get_property(dp, "linux,part-probe", &cplen);
124 if (cp == NULL)
125 return part_probe_types_def;
126
127 count = 0;
128 for (l = 0; l != cplen; l++)
129 if (cp[l] == 0)
130 count++;
131
132 res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
7e0c19c9
CIK
133 if (!res)
134 return NULL;
9d5da3a9
JG
135 count = 0;
136 while (cplen > 0) {
137 res[count] = cp;
138 l = strlen(cp) + 1;
139 cp += l;
140 cplen -= l;
141 count++;
142 }
143 return res;
144}
145
cce2a026 146static void of_free_probes(const char * const *probes)
9d5da3a9
JG
147{
148 if (probes != part_probe_types_def)
149 kfree(probes);
150}
9d5da3a9 151
66610443 152static const struct of_device_id of_flash_match[];
06f25510 153static int of_flash_probe(struct platform_device *dev)
a2c2fe4b 154{
cce2a026 155 const char * const *part_probe_types;
b1608d69 156 const struct of_device_id *match;
61c7a080 157 struct device_node *dp = dev->dev.of_node;
a2c2fe4b 158 struct resource res;
c4d5e375 159 struct of_flash *info;
1c48a5c9 160 const char *probe_type;
766f271a 161 const __be32 *width;
a2c2fe4b 162 int err;
143070e7
SR
163 int i;
164 int count;
766f271a 165 const __be32 *p;
143070e7
SR
166 int reg_tuple_size;
167 struct mtd_info **mtd_list = NULL;
2763c508 168 resource_size_t res_size;
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 }
3fc1cf5f
JS
273
274 /* Fall back to mapping region as ROM */
275 if (!info->list[i].mtd) {
276 dev_warn(&dev->dev,
277 "do_map_probe() failed for type %s\n",
278 probe_type);
279
280 info->list[i].mtd = do_map_probe("map_rom",
281 &info->list[i].map);
282 }
143070e7 283 mtd_list[i] = info->list[i].mtd;
a2c2fe4b 284
143070e7
SR
285 err = -ENXIO;
286 if (!info->list[i].mtd) {
287 dev_err(&dev->dev, "do_map_probe() failed\n");
288 goto err_out;
289 } else {
290 info->list_size++;
291 }
143070e7
SR
292 info->list[i].mtd->dev.parent = &dev->dev;
293 }
2099172d 294
143070e7 295 err = 0;
e58a66d8 296 info->cmtd = NULL;
143070e7
SR
297 if (info->list_size == 1) {
298 info->cmtd = info->list[0].mtd;
299 } else if (info->list_size > 1) {
300 /*
301 * We detected multiple devices. Concatenate them together.
302 */
143070e7
SR
303 info->cmtd = mtd_concat_create(mtd_list, info->list_size,
304 dev_name(&dev->dev));
a2c2fe4b 305 }
e58a66d8
AP
306 if (info->cmtd == NULL)
307 err = -ENXIO;
308
143070e7
SR
309 if (err)
310 goto err_out;
a2c2fe4b 311
004b5e60 312 mtd_set_of_node(info->cmtd, dp);
9d5da3a9 313 part_probe_types = of_get_probes(dp);
7e0c19c9
CIK
314 if (!part_probe_types) {
315 err = -ENOMEM;
316 goto err_out;
317 }
004b5e60 318 mtd_device_parse_register(info->cmtd, part_probe_types, NULL,
f44dcbd0 319 NULL, 0);
9d5da3a9 320 of_free_probes(part_probe_types);
9a310d21 321
143070e7 322 kfree(mtd_list);
a2c2fe4b 323
a2c2fe4b
VW
324 return 0;
325
326err_out:
143070e7 327 kfree(mtd_list);
ad4fbc79 328err_flash_remove:
c4d5e375 329 of_flash_remove(dev);
143070e7 330
a2c2fe4b 331 return err;
a2c2fe4b
VW
332}
333
66610443 334static const struct of_device_id of_flash_match[] = {
2099172d
DG
335 {
336 .compatible = "cfi-flash",
337 .data = (void *)"cfi_probe",
338 },
339 {
340 /* FIXME: JEDEC chips can't be safely and reliably
341 * probed, although the mtd code gets it right in
342 * practice most of the time. We should use the
343 * vendor and device ids specified by the binding to
344 * bypass the heuristic probe code, but the mtd layer
345 * provides, at present, no interface for doing so
346 * :(. */
347 .compatible = "jedec-flash",
348 .data = (void *)"jedec_probe",
349 },
fc28c39f
WS
350 {
351 .compatible = "mtd-ram",
352 .data = (void *)"map_ram",
353 },
e5bffb59
AS
354 {
355 .compatible = "mtd-rom",
356 .data = (void *)"map_rom",
357 },
a2c2fe4b
VW
358 {
359 .type = "rom",
360 .compatible = "direct-mapped"
361 },
362 { },
363};
c4d5e375 364MODULE_DEVICE_TABLE(of, of_flash_match);
a2c2fe4b 365
1c48a5c9 366static struct platform_driver of_flash_driver = {
4018294b
GL
367 .driver = {
368 .name = "of-flash",
4018294b
GL
369 .of_match_table = of_flash_match,
370 },
c4d5e375
DG
371 .probe = of_flash_probe,
372 .remove = of_flash_remove,
a2c2fe4b
VW
373};
374
f99640de 375module_platform_driver(of_flash_driver);
a2c2fe4b
VW
376
377MODULE_LICENSE("GPL");
378MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
c4d5e375 379MODULE_DESCRIPTION("Device tree based MTD map driver");
This page took 0.5301 seconds and 5 git commands to generate.