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/of.h>
24#include <linux/of_address.h>
25#include <linux/of_platform.h>
26#include <linux/slab.h>
27
28struct of_flash_list {
29	struct mtd_info *mtd;
30	struct map_info map;
31	struct resource *res;
32};
33
34struct of_flash {
35	struct mtd_info		*cmtd;
36	int list_size; /* number of elements in of_flash_list */
37	struct of_flash_list	list[0];
38};
39
40static int of_flash_remove(struct platform_device *dev)
41{
42	struct of_flash *info;
43	int i;
44
45	info = dev_get_drvdata(&dev->dev);
46	if (!info)
47		return 0;
48	dev_set_drvdata(&dev->dev, NULL);
49
50	if (info->cmtd) {
51		mtd_device_unregister(info->cmtd);
52		if (info->cmtd != info->list[0].mtd)
53			mtd_concat_destroy(info->cmtd);
54	}
55
56	for (i = 0; i < info->list_size; i++) {
57		if (info->list[i].mtd)
58			map_destroy(info->list[i].mtd);
59
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		}
67	}
68	return 0;
69}
70
71static const char * const rom_probe_types[] = {
72	"cfi_probe", "jedec_probe", "map_rom" };
73
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. */
77static struct mtd_info *obsolete_probe(struct platform_device *dev,
78				       struct map_info *map)
79{
80	struct device_node *dp = dev->dev.of_node;
81	const char *of_probe;
82	struct mtd_info *mtd;
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)
102			dev_warn(&dev->dev, "obsolete_probe: don't know probe "
103				 "type '%s', mapping as rom\n", of_probe);
104		return do_map_probe("map_rom", map);
105	}
106}
107
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. */
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)
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);
133	if (!res)
134		return NULL;
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
146static void of_free_probes(const char * const *probes)
147{
148	if (probes != part_probe_types_def)
149		kfree(probes);
150}
151
152static const struct of_device_id of_flash_match[];
153static int of_flash_probe(struct platform_device *dev)
154{
155	const char * const *part_probe_types;
156	const struct of_device_id *match;
157	struct device_node *dp = dev->dev.of_node;
158	struct resource res;
159	struct of_flash *info;
160	const char *probe_type;
161	const __be32 *width;
162	int err;
163	int i;
164	int count;
165	const __be32 *p;
166	int reg_tuple_size;
167	struct mtd_info **mtd_list = NULL;
168	resource_size_t res_size;
169	struct mtd_part_parser_data ppdata;
170	bool map_indirect;
171	const char *mtd_name = NULL;
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	of_property_read_string(dp, "linux,mtd-name", &mtd_name);
181
182	/*
183	 * Get number of "reg" tuples. Scan for MTD devices on area's
184	 * described by each "reg" region. This makes it possible (including
185	 * the concat support) to support the Intel P30 48F4400 chips which
186	 * consists internally of 2 non-identical NOR chips on one die.
187	 */
188	p = of_get_property(dp, "reg", &count);
189	if (count % reg_tuple_size != 0) {
190		dev_err(&dev->dev, "Malformed reg property on %s\n",
191				dev->dev.of_node->full_name);
192		err = -EINVAL;
193		goto err_flash_remove;
194	}
195	count /= reg_tuple_size;
196
197	map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access");
198
199	err = -ENOMEM;
200	info = devm_kzalloc(&dev->dev,
201			    sizeof(struct of_flash) +
202			    sizeof(struct of_flash_list) * count, GFP_KERNEL);
203	if (!info)
204		goto err_flash_remove;
205
206	dev_set_drvdata(&dev->dev, info);
207
208	mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
209	if (!mtd_list)
210		goto err_flash_remove;
211
212	for (i = 0; i < count; i++) {
213		err = -ENXIO;
214		if (of_address_to_resource(dp, i, &res)) {
215			/*
216			 * Continue with next register tuple if this
217			 * one is not mappable
218			 */
219			continue;
220		}
221
222		dev_dbg(&dev->dev, "of_flash device: %pR\n", &res);
223
224		err = -EBUSY;
225		res_size = resource_size(&res);
226		info->list[i].res = request_mem_region(res.start, res_size,
227						       dev_name(&dev->dev));
228		if (!info->list[i].res)
229			goto err_out;
230
231		err = -ENXIO;
232		width = of_get_property(dp, "bank-width", NULL);
233		if (!width) {
234			dev_err(&dev->dev, "Can't get bank width from device"
235				" tree\n");
236			goto err_out;
237		}
238
239		info->list[i].map.name = mtd_name ?: dev_name(&dev->dev);
240		info->list[i].map.phys = res.start;
241		info->list[i].map.size = res_size;
242		info->list[i].map.bankwidth = be32_to_cpup(width);
243		info->list[i].map.device_node = dp;
244
245		err = -ENOMEM;
246		info->list[i].map.virt = ioremap(info->list[i].map.phys,
247						 info->list[i].map.size);
248		if (!info->list[i].map.virt) {
249			dev_err(&dev->dev, "Failed to ioremap() flash"
250				" region\n");
251			goto err_out;
252		}
253
254		simple_map_init(&info->list[i].map);
255
256		/*
257		 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
258		 * may cause problems with JFFS2 usage, as the local bus (LPB)
259		 * doesn't support unaligned accesses as implemented in the
260		 * JFFS2 code via memcpy(). By setting NO_XIP, the
261		 * flash will not be exposed directly to the MTD users
262		 * (e.g. JFFS2) any more.
263		 */
264		if (map_indirect)
265			info->list[i].map.phys = NO_XIP;
266
267		if (probe_type) {
268			info->list[i].mtd = do_map_probe(probe_type,
269							 &info->list[i].map);
270		} else {
271			info->list[i].mtd = obsolete_probe(dev,
272							   &info->list[i].map);
273		}
274
275		/* Fall back to mapping region as ROM */
276		if (!info->list[i].mtd) {
277			dev_warn(&dev->dev,
278				"do_map_probe() failed for type %s\n",
279				 probe_type);
280
281			info->list[i].mtd = do_map_probe("map_rom",
282							 &info->list[i].map);
283		}
284		mtd_list[i] = info->list[i].mtd;
285
286		err = -ENXIO;
287		if (!info->list[i].mtd) {
288			dev_err(&dev->dev, "do_map_probe() failed\n");
289			goto err_out;
290		} else {
291			info->list_size++;
292		}
293		info->list[i].mtd->dev.parent = &dev->dev;
294	}
295
296	err = 0;
297	info->cmtd = NULL;
298	if (info->list_size == 1) {
299		info->cmtd = info->list[0].mtd;
300	} else if (info->list_size > 1) {
301		/*
302		 * We detected multiple devices. Concatenate them together.
303		 */
304		info->cmtd = mtd_concat_create(mtd_list, info->list_size,
305					       dev_name(&dev->dev));
306	}
307	if (info->cmtd == NULL)
308		err = -ENXIO;
309
310	if (err)
311		goto err_out;
312
313	ppdata.of_node = dp;
314	part_probe_types = of_get_probes(dp);
315	if (!part_probe_types) {
316		err = -ENOMEM;
317		goto err_out;
318	}
319	mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
320			NULL, 0);
321	of_free_probes(part_probe_types);
322
323	kfree(mtd_list);
324
325	return 0;
326
327err_out:
328	kfree(mtd_list);
329err_flash_remove:
330	of_flash_remove(dev);
331
332	return err;
333}
334
335static const struct of_device_id of_flash_match[] = {
336	{
337		.compatible	= "cfi-flash",
338		.data		= (void *)"cfi_probe",
339	},
340	{
341		/* FIXME: JEDEC chips can't be safely and reliably
342		 * probed, although the mtd code gets it right in
343		 * practice most of the time.  We should use the
344		 * vendor and device ids specified by the binding to
345		 * bypass the heuristic probe code, but the mtd layer
346		 * provides, at present, no interface for doing so
347		 * :(. */
348		.compatible	= "jedec-flash",
349		.data		= (void *)"jedec_probe",
350	},
351	{
352		.compatible     = "mtd-ram",
353		.data           = (void *)"map_ram",
354	},
355	{
356		.compatible     = "mtd-rom",
357		.data           = (void *)"map_rom",
358	},
359	{
360		.type		= "rom",
361		.compatible	= "direct-mapped"
362	},
363	{ },
364};
365MODULE_DEVICE_TABLE(of, of_flash_match);
366
367static struct platform_driver of_flash_driver = {
368	.driver = {
369		.name = "of-flash",
370		.of_match_table = of_flash_match,
371	},
372	.probe		= of_flash_probe,
373	.remove		= of_flash_remove,
374};
375
376module_platform_driver(of_flash_driver);
377
378MODULE_LICENSE("GPL");
379MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
380MODULE_DESCRIPTION("Device tree based MTD map driver");
381