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