diff options
author | Scott Wood <scottwood@freescale.com> | 2008-01-15 17:54:43 -0600 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-02-03 18:06:48 +1100 |
commit | 9a310d21196f38f6ad0ad146057548653e495c09 (patch) | |
tree | ea623f5d0f8712bd300e6bebf5695a3e124cb9cb /drivers/mtd/ofpart.c | |
parent | c0d2a48a65a8fc286aa84871cfc20d8c10dbf492 (diff) |
[MTD] Factor out OF partition support from the NOR driver.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'drivers/mtd/ofpart.c')
-rw-r--r-- | drivers/mtd/ofpart.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c new file mode 100644 index 000000000000..f86e06934cd8 --- /dev/null +++ b/drivers/mtd/ofpart.c @@ -0,0 +1,74 @@ +/* + * Flash partitions described by the OF (or flattened) device tree + * + * Copyright (C) 2006 MontaVista Software Inc. + * Author: Vitaly Wool <vwool@ru.mvista.com> + * + * Revised to handle newer style flash binding by: + * Copyright (C) 2007 David Gibson, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/of.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> + +int __devinit of_mtd_parse_partitions(struct device *dev, + struct mtd_info *mtd, + struct device_node *node, + struct mtd_partition **pparts) +{ + const char *partname; + struct device_node *pp; + int nr_parts, i; + + /* First count the subnodes */ + pp = NULL; + nr_parts = 0; + while ((pp = of_get_next_child(node, pp))) + nr_parts++; + + if (nr_parts == 0) + return 0; + + *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL); + if (!*pparts) + return -ENOMEM; + + pp = NULL; + i = 0; + while ((pp = of_get_next_child(node, pp))) { + const u32 *reg; + int len; + + reg = of_get_property(pp, "reg", &len); + if (!reg || (len != 2 * sizeof(u32))) { + of_node_put(pp); + dev_err(dev, "Invalid 'reg' on %s\n", node->full_name); + kfree(*pparts); + *pparts = NULL; + return -EINVAL; + } + (*pparts)[i].offset = reg[0]; + (*pparts)[i].size = reg[1]; + + partname = of_get_property(pp, "label", &len); + if (!partname) + partname = of_get_property(pp, "name", &len); + (*pparts)[i].name = (char *)partname; + + if (of_get_property(pp, "read-only", &len)) + (*pparts)[i].mask_flags = MTD_WRITEABLE; + + i++; + } + + return nr_parts; +} +EXPORT_SYMBOL(of_mtd_parse_partitions); |