Linux Audio

Check our new training course

Linux BSP upgrade and security maintenance

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