summary refs log tree commit diff
path: root/drivers/mtd/mtdcore.c
diff options
context:
space:
mode:
authorDan Ehrenberg <dehrenberg@chromium.org>2015-04-02 15:15:10 -0700
committerBrian Norris <computersforpeace@gmail.com>2015-04-05 17:44:01 -0700
commit727dc612c46b8f3858537ea23805b3e897cf127e (patch)
tree5bcda420d5f0071fc8d8c8c02dc68166256323e7 /drivers/mtd/mtdcore.c
parent9cd5196ed25979a3760f97225aae3e17caf21512 (diff)
downloadlinux-727dc612c46b8f3858537ea23805b3e897cf127e.tar.gz
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.c52
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);