diff options
author | Dan Ehrenberg <dehrenberg@chromium.org> | 2015-04-02 15:15:10 -0700 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2015-04-05 17:44:01 -0700 |
commit | 727dc612c46b8f3858537ea23805b3e897cf127e (patch) | |
tree | 5bcda420d5f0071fc8d8c8c02dc68166256323e7 /drivers/mtd/mtdcore.c | |
parent | 9cd5196ed25979a3760f97225aae3e17caf21512 (diff) | |
download | lwn-727dc612c46b8f3858537ea23805b3e897cf127e.tar.gz lwn-727dc612c46b8f3858537ea23805b3e897cf127e.zip |
mtd: part: Create the master device node when partitioned
For many use cases, it helps to have a device node for the entire
MTD device as well as device nodes for the individual partitions.
For example, this allows querying the entire device's properties.
A common idiom is to create an additional partition which spans
over the whole device.
This patch makes a config option, CONFIG_MTD_PARTITIONED_MASTER,
which makes the master partition present even when the device is
partitioned. This isn't turned on by default since it presents
a backwards-incompatible device numbering.
The patch also makes the parent of a partition device be the master,
if the config flag is set, now that the master is a full device.
Signed-off-by: Dan Ehrenberg <dehrenberg@chromium.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/mtdcore.c')
-rw-r--r-- | drivers/mtd/mtdcore.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 11883bd26d9d..d172195fbd15 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -38,6 +38,7 @@ #include <linux/gfp.h> #include <linux/slab.h> #include <linux/reboot.h> +#include <linux/kconfig.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> @@ -501,6 +502,29 @@ out_error: return ret; } +static int mtd_add_device_partitions(struct mtd_info *mtd, + struct mtd_partition *real_parts, + int nbparts) +{ + int ret; + + if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { + ret = add_mtd_device(mtd); + if (ret == 1) + return -ENODEV; + } + + if (nbparts > 0) { + ret = add_mtd_partitions(mtd, real_parts, nbparts); + if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) + del_mtd_device(mtd); + return ret; + } + + return 0; +} + + /** * mtd_device_parse_register - parse partitions and register an MTD device. * @@ -523,7 +547,8 @@ out_error: * found this functions tries to fallback to information specified in * @parts/@nr_parts. * * If any partitioning info was found, this function registers the found - * partitions. + * partitions. If the MTD_PARTITIONED_MASTER option is set, then the device + * as a whole is registered first. * * If no partitions were found this function just registers the MTD device * @mtd and exits. * @@ -534,27 +559,21 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, const struct mtd_partition *parts, int nr_parts) { - int err; - struct mtd_partition *real_parts; + int ret; + struct mtd_partition *real_parts = NULL; - err = parse_mtd_partitions(mtd, types, &real_parts, parser_data); - if (err <= 0 && nr_parts && parts) { + ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); + if (ret <= 0 && nr_parts && parts) { real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, GFP_KERNEL); if (!real_parts) - err = -ENOMEM; + ret = -ENOMEM; else - err = nr_parts; + ret = nr_parts; } - if (err > 0) { - err = add_mtd_partitions(mtd, real_parts, err); - kfree(real_parts); - } else if (err == 0) { - err = add_mtd_device(mtd); - if (err == 1) - err = -ENODEV; - } + if (ret >= 0) + ret = mtd_add_device_partitions(mtd, real_parts, ret); /* * FIXME: some drivers unfortunately call this function more than once. @@ -569,7 +588,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, register_reboot_notifier(&mtd->reboot_notifier); } - return err; + kfree(real_parts); + return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); |