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/init.h>
19 #include <linux/device.h>
20 #include <linux/mtd/mtd.h>
21 #include <linux/mtd/map.h>
22 #include <linux/mtd/partitions.h>
23 #include <linux/mtd/concat.h>
24 #include <linux/of.h>
25 #include <linux/of_address.h>
26 #include <linux/of_platform.h>
27 #include <linux/slab.h>
28 
29 struct of_flash_list {
30 	struct mtd_info *mtd;
31 	struct map_info map;
32 	struct resource *res;
33 };
34 
35 struct of_flash {
36 	struct mtd_info		*cmtd;
37 	int list_size; /* number of elements in of_flash_list */
38 	struct of_flash_list	list[0];
39 };
40 
of_flash_remove(struct platform_device * dev)41 static int of_flash_remove(struct platform_device *dev)
42 {
43 	struct of_flash *info;
44 	int i;
45 
46 	info = dev_get_drvdata(&dev->dev);
47 	if (!info)
48 		return 0;
49 	dev_set_drvdata(&dev->dev, NULL);
50 
51 	if (info->cmtd != info->list[0].mtd) {
52 		mtd_device_unregister(info->cmtd);
53 		mtd_concat_destroy(info->cmtd);
54 	}
55 
56 	if (info->cmtd)
57 		mtd_device_unregister(info->cmtd);
58 
59 	for (i = 0; i < info->list_size; i++) {
60 		if (info->list[i].mtd)
61 			map_destroy(info->list[i].mtd);
62 
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 		}
70 	}
71 
72 	kfree(info);
73 
74 	return 0;
75 }
76 
77 /* Helper function to handle probing of the obsolete "direct-mapped"
78  * compatible binding, which has an extra "probe-type" property
79  * describing the type of flash probe necessary. */
obsolete_probe(struct platform_device * dev,struct map_info * map)80 static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev,
81 						  struct map_info *map)
82 {
83 	struct device_node *dp = dev->dev.of_node;
84 	const char *of_probe;
85 	struct mtd_info *mtd;
86 	static const char *rom_probe_types[]
87 		= { "cfi_probe", "jedec_probe", "map_rom"};
88 	int i;
89 
90 	dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" "
91 		 "flash binding\n");
92 
93 	of_probe = of_get_property(dp, "probe-type", NULL);
94 	if (!of_probe) {
95 		for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) {
96 			mtd = do_map_probe(rom_probe_types[i], map);
97 			if (mtd)
98 				return mtd;
99 		}
100 		return NULL;
101 	} else if (strcmp(of_probe, "CFI") == 0) {
102 		return do_map_probe("cfi_probe", map);
103 	} else if (strcmp(of_probe, "JEDEC") == 0) {
104 		return do_map_probe("jedec_probe", map);
105 	} else {
106 		if (strcmp(of_probe, "ROM") != 0)
107 			dev_warn(&dev->dev, "obsolete_probe: don't know probe "
108 				 "type '%s', mapping as rom\n", of_probe);
109 		return do_map_probe("mtd_rom", map);
110 	}
111 }
112 
113 /* When partitions are set we look for a linux,part-probe property which
114    specifies the list of partition probers to use. If none is given then the
115    default is use. These take precedence over other device tree
116    information. */
117 static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot",
118 					"ofpart", "ofoldpart", NULL };
of_get_probes(struct device_node * dp)119 static const char ** __devinit of_get_probes(struct device_node *dp)
120 {
121 	const char *cp;
122 	int cplen;
123 	unsigned int l;
124 	unsigned int count;
125 	const char **res;
126 
127 	cp = of_get_property(dp, "linux,part-probe", &cplen);
128 	if (cp == NULL)
129 		return part_probe_types_def;
130 
131 	count = 0;
132 	for (l = 0; l != cplen; l++)
133 		if (cp[l] == 0)
134 			count++;
135 
136 	res = kzalloc((count + 1)*sizeof(*res), GFP_KERNEL);
137 	count = 0;
138 	while (cplen > 0) {
139 		res[count] = cp;
140 		l = strlen(cp) + 1;
141 		cp += l;
142 		cplen -= l;
143 		count++;
144 	}
145 	return res;
146 }
147 
of_free_probes(const char ** probes)148 static void __devinit of_free_probes(const char **probes)
149 {
150 	if (probes != part_probe_types_def)
151 		kfree(probes);
152 }
153 
154 static struct of_device_id of_flash_match[];
of_flash_probe(struct platform_device * dev)155 static int __devinit of_flash_probe(struct platform_device *dev)
156 {
157 	const char **part_probe_types;
158 	const struct of_device_id *match;
159 	struct device_node *dp = dev->dev.of_node;
160 	struct resource res;
161 	struct of_flash *info;
162 	const char *probe_type;
163 	const __be32 *width;
164 	int err;
165 	int i;
166 	int count;
167 	const __be32 *p;
168 	int reg_tuple_size;
169 	struct mtd_info **mtd_list = NULL;
170 	resource_size_t res_size;
171 	struct mtd_part_parser_data ppdata;
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 	/*
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 	err = -ENOMEM;
196 	info = kzalloc(sizeof(struct of_flash) +
197 		       sizeof(struct of_flash_list) * count, GFP_KERNEL);
198 	if (!info)
199 		goto err_flash_remove;
200 
201 	dev_set_drvdata(&dev->dev, info);
202 
203 	mtd_list = kzalloc(sizeof(*mtd_list) * count, GFP_KERNEL);
204 	if (!mtd_list)
205 		goto err_flash_remove;
206 
207 	for (i = 0; i < count; i++) {
208 		err = -ENXIO;
209 		if (of_address_to_resource(dp, i, &res)) {
210 			/*
211 			 * Continue with next register tuple if this
212 			 * one is not mappable
213 			 */
214 			continue;
215 		}
216 
217 		dev_dbg(&dev->dev, "of_flash device: %pR\n", &res);
218 
219 		err = -EBUSY;
220 		res_size = resource_size(&res);
221 		info->list[i].res = request_mem_region(res.start, res_size,
222 						       dev_name(&dev->dev));
223 		if (!info->list[i].res)
224 			goto err_out;
225 
226 		err = -ENXIO;
227 		width = of_get_property(dp, "bank-width", NULL);
228 		if (!width) {
229 			dev_err(&dev->dev, "Can't get bank width from device"
230 				" tree\n");
231 			goto err_out;
232 		}
233 
234 		info->list[i].map.name = dev_name(&dev->dev);
235 		info->list[i].map.phys = res.start;
236 		info->list[i].map.size = res_size;
237 		info->list[i].map.bankwidth = be32_to_cpup(width);
238 
239 		err = -ENOMEM;
240 		info->list[i].map.virt = ioremap(info->list[i].map.phys,
241 						 info->list[i].map.size);
242 		if (!info->list[i].map.virt) {
243 			dev_err(&dev->dev, "Failed to ioremap() flash"
244 				" region\n");
245 			goto err_out;
246 		}
247 
248 		simple_map_init(&info->list[i].map);
249 
250 		if (probe_type) {
251 			info->list[i].mtd = do_map_probe(probe_type,
252 							 &info->list[i].map);
253 		} else {
254 			info->list[i].mtd = obsolete_probe(dev,
255 							   &info->list[i].map);
256 		}
257 		mtd_list[i] = info->list[i].mtd;
258 
259 		err = -ENXIO;
260 		if (!info->list[i].mtd) {
261 			dev_err(&dev->dev, "do_map_probe() failed\n");
262 			goto err_out;
263 		} else {
264 			info->list_size++;
265 		}
266 		info->list[i].mtd->owner = THIS_MODULE;
267 		info->list[i].mtd->dev.parent = &dev->dev;
268 	}
269 
270 	err = 0;
271 	if (info->list_size == 1) {
272 		info->cmtd = info->list[0].mtd;
273 	} else if (info->list_size > 1) {
274 		/*
275 		 * We detected multiple devices. Concatenate them together.
276 		 */
277 		info->cmtd = mtd_concat_create(mtd_list, info->list_size,
278 					       dev_name(&dev->dev));
279 		if (info->cmtd == NULL)
280 			err = -ENXIO;
281 	}
282 	if (err)
283 		goto err_out;
284 
285 	ppdata.of_node = dp;
286 	part_probe_types = of_get_probes(dp);
287 	mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata,
288 			NULL, 0);
289 	of_free_probes(part_probe_types);
290 
291 	kfree(mtd_list);
292 
293 	return 0;
294 
295 err_out:
296 	kfree(mtd_list);
297 err_flash_remove:
298 	of_flash_remove(dev);
299 
300 	return err;
301 }
302 
303 static struct of_device_id of_flash_match[] = {
304 	{
305 		.compatible	= "cfi-flash",
306 		.data		= (void *)"cfi_probe",
307 	},
308 	{
309 		/* FIXME: JEDEC chips can't be safely and reliably
310 		 * probed, although the mtd code gets it right in
311 		 * practice most of the time.  We should use the
312 		 * vendor and device ids specified by the binding to
313 		 * bypass the heuristic probe code, but the mtd layer
314 		 * provides, at present, no interface for doing so
315 		 * :(. */
316 		.compatible	= "jedec-flash",
317 		.data		= (void *)"jedec_probe",
318 	},
319 	{
320 		.compatible     = "mtd-ram",
321 		.data           = (void *)"map_ram",
322 	},
323 	{
324 		.type		= "rom",
325 		.compatible	= "direct-mapped"
326 	},
327 	{ },
328 };
329 MODULE_DEVICE_TABLE(of, of_flash_match);
330 
331 static struct platform_driver of_flash_driver = {
332 	.driver = {
333 		.name = "of-flash",
334 		.owner = THIS_MODULE,
335 		.of_match_table = of_flash_match,
336 	},
337 	.probe		= of_flash_probe,
338 	.remove		= of_flash_remove,
339 };
340 
341 module_platform_driver(of_flash_driver);
342 
343 MODULE_LICENSE("GPL");
344 MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");
345 MODULE_DESCRIPTION("Device tree based MTD map driver");
346