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