diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-07 09:11:16 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-07 09:11:16 -0800 |
commit | e0d65113a70f1dc514e625cc4e7a7485a4bf72df (patch) | |
tree | 7320a130dc304623f5cf4b5dd8f67fb1776225ca /drivers/mtd/ofpart.c | |
parent | cf5e15fbd72c13977720aa15b7b7e00e1d8fd8f2 (diff) | |
parent | 48e546b7f281f251893baa40769581fd15f085fb (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (226 commits)
mtd: tests: annotate as DANGEROUS in Kconfig
mtd: tests: don't use mtd0 as a default
mtd: clean up usage of MTD_DOCPROBE_ADDRESS
jffs2: add compr=lzo and compr=zlib options
jffs2: implement mount option parsing and compression overriding
mtd: nand: initialize ops.mode
mtd: provide an alias for the redboot module name
mtd: m25p80: don't probe device which has status of 'disabled'
mtd: nand_h1900 never worked
mtd: Add DiskOnChip G3 support
mtd: m25p80: add EON flash EN25Q32B into spi flash id table
mtd: mark block device queue as non-rotational
mtd: r852: make r852_pm_ops static
mtd: m25p80: add support for at25df321a spi data flash
mtd: mxc_nand: preset_v1_v2: unlock all NAND flash blocks
mtd: nand: switch `check_pattern()' to standard `memcmp()'
mtd: nand: invalidate cache on unaligned reads
mtd: nand: do not scan bad blocks with NAND_BBT_NO_OOB set
mtd: nand: wait to set BBT version
mtd: nand: scrub BBT on ECC errors
...
Fix up trivial conflicts:
- arch/arm/mach-at91/board-usb-a9260.c
Merged into board-usb-a926x.c
- drivers/mtd/maps/lantiq-flash.c
add_mtd_partitions -> mtd_device_register vs changed to use
mtd_device_parse_register.
Diffstat (limited to 'drivers/mtd/ofpart.c')
-rw-r--r-- | drivers/mtd/ofpart.c | 112 |
1 files changed, 107 insertions, 5 deletions
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index a996718fa6b..64be8f0848b 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -20,14 +20,23 @@ #include <linux/slab.h> #include <linux/mtd/partitions.h> -int __devinit of_mtd_parse_partitions(struct device *dev, - struct device_node *node, - struct mtd_partition **pparts) +static int parse_ofpart_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) { + struct device_node *node; const char *partname; struct device_node *pp; int nr_parts, i; + + if (!data) + return 0; + + node = data->of_node; + if (!node) + return 0; + /* First count the subnodes */ pp = NULL; nr_parts = 0; @@ -69,7 +78,7 @@ int __devinit of_mtd_parse_partitions(struct device *dev, if (!i) { of_node_put(pp); - dev_err(dev, "No valid partition found on %s\n", node->full_name); + pr_err("No valid partition found on %s\n", node->full_name); kfree(*pparts); *pparts = NULL; return -EINVAL; @@ -77,6 +86,99 @@ int __devinit of_mtd_parse_partitions(struct device *dev, return nr_parts; } -EXPORT_SYMBOL(of_mtd_parse_partitions); + +static struct mtd_part_parser ofpart_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_ofpart_partitions, + .name = "ofpart", +}; + +static int parse_ofoldpart_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct device_node *dp; + int i, plen, nr_parts; + const struct { + __be32 offset, len; + } *part; + const char *names; + + if (!data) + return 0; + + dp = data->of_node; + if (!dp) + return 0; + + part = of_get_property(dp, "partitions", &plen); + if (!part) + return 0; /* No partitions found */ + + pr_warning("Device tree uses obsolete partition map binding: %s\n", + dp->full_name); + + nr_parts = plen / sizeof(part[0]); + + *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); + if (!pparts) + return -ENOMEM; + + names = of_get_property(dp, "partition-names", &plen); + + for (i = 0; i < nr_parts; i++) { + (*pparts)[i].offset = be32_to_cpu(part->offset); + (*pparts)[i].size = be32_to_cpu(part->len) & ~1; + /* bit 0 set signifies read only partition */ + if (be32_to_cpu(part->len) & 1) + (*pparts)[i].mask_flags = MTD_WRITEABLE; + + if (names && (plen > 0)) { + int len = strlen(names) + 1; + + (*pparts)[i].name = (char *)names; + plen -= len; + names += len; + } else { + (*pparts)[i].name = "unnamed"; + } + + part++; + } + + return nr_parts; +} + +static struct mtd_part_parser ofoldpart_parser = { + .owner = THIS_MODULE, + .parse_fn = parse_ofoldpart_partitions, + .name = "ofoldpart", +}; + +static int __init ofpart_parser_init(void) +{ + int rc; + rc = register_mtd_parser(&ofpart_parser); + if (rc) + goto out; + + rc = register_mtd_parser(&ofoldpart_parser); + if (!rc) + return 0; + + deregister_mtd_parser(&ofoldpart_parser); +out: + return rc; +} + +module_init(ofpart_parser_init); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree"); +MODULE_AUTHOR("Vitaly Wool, David Gibson"); +/* + * When MTD core cannot find the requested parser, it tries to load the module + * with the same name. Since we provide the ofoldpart parser, we should have + * the corresponding alias. + */ +MODULE_ALIAS("ofoldpart"); |