|
@@ -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);
|
|
|
|