History

Revert "mtd: core: always create master device"

The idea behind this patch was to always let a "master" mtd device available to anchor runtime PM. Historically, there was no mtd device representing the whole storage as soon as partitions were coming into play. The introduction of CONFIG_MTD_PARTITIONED_MASTER allowed to keep this "master" device, but was not enabled by default to avoid breaking existing users (otherwise the mtd device numbering would be totally messed up with an off by 1, at least). The approach of adding an mtd_master class on top of partitioned mtd devices is breaking the mtd core in many creative ways, so better think again this approach and revert the faulty changes for now. This reverts commit 0aa7b390fc40a871267a2328bbbefca8b37ad307.

Miquel Raynal committed 1 year ago

Commit 635e1181 parent 19272b35 files · +51 −123Browse files

Unified · Split

5 files
  1. drivers/mtd/mtdchar.c +1 −1
  2. drivers/mtd/mtdcore.c +40 −112
  3. drivers/mtd/mtdcore.h +1 −1
  4. drivers/mtd/mtdpart.c +8 −8
  5. include/linux/mtd/partitions.h +1 −1
drivers/mtd/mtdchar.c+1−1
@@ -559,7 +559,7 @@ static int mtdchar_blkpg_ioctl(struct mtd_info *mtd, · 558 unmodified lines
559 /* Sanitize user input */559 /* Sanitize user input */
560 p.devname[BLKPG_DEVNAMELTH - 1] = '\0';560 p.devname[BLKPG_DEVNAMELTH - 1] = '\0';
561 561
562 return mtd_add_partition(mtd, p.devname, p.start, p.length, NULL);562 return mtd_add_partition(mtd, p.devname, p.start, p.length);
563 563
564 case BLKPG_DEL_PARTITION:564 case BLKPG_DEL_PARTITION:
565 565
drivers/mtd/mtdcore.c+40−112
@@ -68,13 +68,7 @@ static struct class mtd_class = { · 67 unmodified lines
68 .pm = MTD_CLS_PM_OPS,68 .pm = MTD_CLS_PM_OPS,
69};69};
70 70
71static struct class mtd_master_class = {
72 .name = "mtd_master",
73 .pm = MTD_CLS_PM_OPS,
74};
75
76static DEFINE_IDR(mtd_idr);71static DEFINE_IDR(mtd_idr);
77static DEFINE_IDR(mtd_master_idr);
78 72
79/* These are exported solely for the purpose of mtd_blkdevs.c. You73/* These are exported solely for the purpose of mtd_blkdevs.c. You
80 should not use them for _anything_ else */74 should not use them for _anything_ else */
@@ -89,9 +83,8 @@ EXPORT_SYMBOL_GPL(__mtd_next_device); · 8 unmodified lines
89 83
90static LIST_HEAD(mtd_notifiers);84static LIST_HEAD(mtd_notifiers);
91 85
92#define MTD_MASTER_DEVS 25586
93#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)87#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
94static dev_t mtd_master_devt;
95 88
96/* REVISIT once MTD uses the driver model better, whoever allocates89/* REVISIT once MTD uses the driver model better, whoever allocates
97 * the mtd_info will probably want to use the release() hook...90 * the mtd_info will probably want to use the release() hook...
@@ -111,17 +104,6 @@ static void mtd_release(struct device *dev) · 13 unmodified lines
111 device_destroy(&mtd_class, index + 1);104 device_destroy(&mtd_class, index + 1);
112}105}
113 106
114static void mtd_master_release(struct device *dev)
115{
116 struct mtd_info *mtd = dev_get_drvdata(dev);
117
118 idr_remove(&mtd_master_idr, mtd->index);
119 of_node_put(mtd_get_of_node(mtd));
120
121 if (mtd_is_partition(mtd))
122 release_mtd_partition(mtd);
123}
124
125static void mtd_device_release(struct kref *kref)107static void mtd_device_release(struct kref *kref)
126{108{
127 struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);109 struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
@@ -385,11 +367,6 @@ static const struct device_type mtd_devtype = { · 257 unmodified lines
385 .release = mtd_release,367 .release = mtd_release,
386};368};
387 369
388static const struct device_type mtd_master_devtype = {
389 .name = "mtd_master",
390 .release = mtd_master_release,
391};
392
393static bool mtd_expert_analysis_mode;370static bool mtd_expert_analysis_mode;
394 371
395#ifdef CONFIG_DEBUG_FS372#ifdef CONFIG_DEBUG_FS
@@ -657,13 +634,13 @@ exit_parent: · 261 unmodified lines
657/**634/**
658 * add_mtd_device - register an MTD device635 * add_mtd_device - register an MTD device
659 * @mtd: pointer to new MTD device info structure636 * @mtd: pointer to new MTD device info structure
660 * @partitioned: create partitioned device
661 *637 *
662 * Add a device to the list of MTD devices present in the system, and638 * Add a device to the list of MTD devices present in the system, and
663 * notify each currently active MTD 'user' of its arrival. Returns639 * notify each currently active MTD 'user' of its arrival. Returns
664 * zero on success or non-zero on failure.640 * zero on success or non-zero on failure.
665 */641 */
666int add_mtd_device(struct mtd_info *mtd, bool partitioned)642
643int add_mtd_device(struct mtd_info *mtd)
667{644{
668 struct device_node *np = mtd_get_of_node(mtd);645 struct device_node *np = mtd_get_of_node(mtd);
669 struct mtd_info *master = mtd_get_master(mtd);646 struct mtd_info *master = mtd_get_master(mtd);
@@ -710,17 +687,10 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 40 unmodified lines
710 ofidx = -1;687 ofidx = -1;
711 if (np)688 if (np)
712 ofidx = of_alias_get_id(np, "mtd");689 ofidx = of_alias_get_id(np, "mtd");
713 if (partitioned) {690 if (ofidx >= 0)
714 if (ofidx >= 0)691 i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
715 i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);692 else
716 else693 i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
717 i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
718 } else {
719 if (ofidx >= 0)
720 i = idr_alloc(&mtd_master_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
721 else
722 i = idr_alloc(&mtd_master_idr, mtd, 0, 0, GFP_KERNEL);
723 }
724 if (i < 0) {694 if (i < 0) {
725 error = i;695 error = i;
726 goto fail_locked;696 goto fail_locked;
@@ -768,18 +738,10 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 41 unmodified lines
768 /* Caller should have set dev.parent to match the738 /* Caller should have set dev.parent to match the
769 * physical device, if appropriate.739 * physical device, if appropriate.
770 */740 */
771 if (partitioned) {741 mtd->dev.type = &mtd_devtype;
772 mtd->dev.type = &mtd_devtype;742 mtd->dev.class = &mtd_class;
773 mtd->dev.class = &mtd_class;743 mtd->dev.devt = MTD_DEVT(i);
774 mtd->dev.devt = MTD_DEVT(i);744 error = dev_set_name(&mtd->dev, "mtd%d", i);
775 dev_set_name(&mtd->dev, "mtd%d", i);
776 error = dev_set_name(&mtd->dev, "mtd%d", i);
777 } else {
778 mtd->dev.type = &mtd_master_devtype;
779 mtd->dev.class = &mtd_master_class;
780 mtd->dev.devt = MKDEV(MAJOR(mtd_master_devt), i);
781 error = dev_set_name(&mtd->dev, "mtd_master%d", i);
782 }
783 if (error)745 if (error)
784 goto fail_devname;746 goto fail_devname;
785 dev_set_drvdata(&mtd->dev, mtd);747 dev_set_drvdata(&mtd->dev, mtd);
@@ -787,7 +749,6 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 1 unmodified line
787 of_node_get(mtd_get_of_node(mtd));749 of_node_get(mtd_get_of_node(mtd));
788 error = device_register(&mtd->dev);750 error = device_register(&mtd->dev);
789 if (error) {751 if (error) {
790 pr_err("mtd: %s device_register fail %d\n", mtd->name, error);
791 put_device(&mtd->dev);752 put_device(&mtd->dev);
792 goto fail_added;753 goto fail_added;
793 }754 }
@@ -799,13 +760,10 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 5 unmodified lines
799 760
800 mtd_debugfs_populate(mtd);761 mtd_debugfs_populate(mtd);
801 762
802 if (partitioned) {763 device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
803 device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,764 "mtd%dro", i);
804 "mtd%dro", i);
805 }
806 765
807 pr_debug("mtd: Giving out %spartitioned device %d to %s\n",766 pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name);
808 partitioned ? "" : "un-", i, mtd->name);
809 /* No need to get a refcount on the module containing767 /* No need to get a refcount on the module containing
810 the notifier, since we hold the mtd_table_mutex */768 the notifier, since we hold the mtd_table_mutex */
811 list_for_each_entry(not, &mtd_notifiers, list)769 list_for_each_entry(not, &mtd_notifiers, list)
@@ -813,16 +771,13 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 1 unmodified line
813 771
814 mutex_unlock(&mtd_table_mutex);772 mutex_unlock(&mtd_table_mutex);
815 773
816 if (partitioned) {774 if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) {
817 if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) {775 if (IS_BUILTIN(CONFIG_MTD)) {
818 if (IS_BUILTIN(CONFIG_MTD)) {776 pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
819 pr_info("mtd: setting mtd%d (%s) as root device\n",777 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
820 mtd->index, mtd->name);778 } else {
821 ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);779 pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
822 } else {780 mtd->index, mtd->name);
823 pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
824 mtd->index, mtd->name);
825 }
826 }781 }
827 }782 }
828 783
@@ -838,10 +793,7 @@ fail_nvmem_add: · 9 unmodified lines
838fail_added:793fail_added:
839 of_node_put(mtd_get_of_node(mtd));794 of_node_put(mtd_get_of_node(mtd));
840fail_devname:795fail_devname:
841 if (partitioned)796 idr_remove(&mtd_idr, i);
842 idr_remove(&mtd_idr, i);
843 else
844 idr_remove(&mtd_master_idr, i);
845fail_locked:797fail_locked:
846 mutex_unlock(&mtd_table_mutex);798 mutex_unlock(&mtd_table_mutex);
847 return error;799 return error;
@@ -859,14 +811,12 @@ fail_locked: · 11 unmodified lines
859 811
860int del_mtd_device(struct mtd_info *mtd)812int del_mtd_device(struct mtd_info *mtd)
861{813{
862 struct mtd_notifier *not;
863 struct idr *idr;
864 int ret;814 int ret;
815 struct mtd_notifier *not;
865 816
866 mutex_lock(&mtd_table_mutex);817 mutex_lock(&mtd_table_mutex);
867 818
868 idr = mtd->dev.class == &mtd_class ? &mtd_idr : &mtd_master_idr;819 if (idr_find(&mtd_idr, mtd->index) != mtd) {
869 if (idr_find(idr, mtd->index) != mtd) {
870 ret = -ENODEV;820 ret = -ENODEV;
871 goto out_error;821 goto out_error;
872 }822 }
@@ -1106,7 +1056,6 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, · 233 unmodified lines
1106 const struct mtd_partition *parts,1056 const struct mtd_partition *parts,
1107 int nr_parts)1057 int nr_parts)
1108{1058{
1109 struct mtd_info *parent;
1110 int ret, err;1059 int ret, err;
1111 1060
1112 mtd_set_dev_defaults(mtd);1061 mtd_set_dev_defaults(mtd);
@@ -1115,30 +1064,25 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, · 2 unmodified lines
1115 if (ret)1064 if (ret)
1116 goto out;1065 goto out;
1117 1066
1118 ret = add_mtd_device(mtd, false);
1119 if (ret)
1120 goto out;
1121
1122 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {1067 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
1123 ret = mtd_add_partition(mtd, mtd->name, 0, MTDPART_SIZ_FULL, &parent);1068 ret = add_mtd_device(mtd);
1124 if (ret)1069 if (ret)
1125 goto out;1070 goto out;
1126
1127 } else {
1128 parent = mtd;
1129 }1071 }
1130 1072
1131 /* Prefer parsed partitions over driver-provided fallback */1073 /* Prefer parsed partitions over driver-provided fallback */
1132 ret = parse_mtd_partitions(parent, types, parser_data);1074 ret = parse_mtd_partitions(mtd, types, parser_data);
1133 if (ret == -EPROBE_DEFER)1075 if (ret == -EPROBE_DEFER)
1134 goto out;1076 goto out;
1135 1077
1136 if (ret > 0)1078 if (ret > 0)
1137 ret = 0;1079 ret = 0;
1138 else if (nr_parts)1080 else if (nr_parts)
1139 ret = add_mtd_partitions(parent, parts, nr_parts);1081 ret = add_mtd_partitions(mtd, parts, nr_parts);
1140 else if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))1082 else if (!device_is_registered(&mtd->dev))
1141 ret = mtd_add_partition(parent, mtd->name, 0, MTDPART_SIZ_FULL, NULL);1083 ret = add_mtd_device(mtd);
1084 else
1085 ret = 0;
1142 1086
1143 if (ret)1087 if (ret)
1144 goto out;1088 goto out;
@@ -1158,14 +1102,13 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, · 13 unmodified lines
1158 register_reboot_notifier(&mtd->reboot_notifier);1102 register_reboot_notifier(&mtd->reboot_notifier);
1159 }1103 }
1160 1104
1161 return 0;
1162out:1105out:
1163 nvmem_unregister(mtd->otp_user_nvmem);1106 if (ret) {
1164 nvmem_unregister(mtd->otp_factory_nvmem);1107 nvmem_unregister(mtd->otp_user_nvmem);
1165 1108 nvmem_unregister(mtd->otp_factory_nvmem);
1166 del_mtd_partitions(mtd);1109 }
1167 1110
1168 if (device_is_registered(&mtd->dev)) {1111 if (ret && device_is_registered(&mtd->dev)) {
1169 err = del_mtd_device(mtd);1112 err = del_mtd_device(mtd);
1170 if (err)1113 if (err)
1171 pr_err("Error when deleting MTD device (%d)\n", err);1114 pr_err("Error when deleting MTD device (%d)\n", err);
@@ -1324,7 +1267,8 @@ int __get_mtd_device(struct mtd_info *mtd) · 152 unmodified lines
1324 mtd = mtd->parent;1267 mtd = mtd->parent;
1325 }1268 }
1326 1269
1327 kref_get(&master->refcnt);1270 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
1271 kref_get(&master->refcnt);
1328 1272
1329 return 0;1273 return 0;
1330}1274}
@@ -1418,7 +1362,8 @@ void __put_mtd_device(struct mtd_info *mtd) · 87 unmodified lines
1418 mtd = parent;1362 mtd = parent;
1419 }1363 }
1420 1364
1421 kref_put(&master->refcnt, mtd_device_release);1365 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
1366 kref_put(&master->refcnt, mtd_device_release);
1422 1367
1423 module_put(master->owner);1368 module_put(master->owner);
1424 1369
@@ -2585,16 +2530,6 @@ static int __init init_mtd(void) · 1160 unmodified lines
2585 if (ret)2530 if (ret)
2586 goto err_reg;2531 goto err_reg;
2587 2532
2588 ret = class_register(&mtd_master_class);
2589 if (ret)
2590 goto err_reg2;
2591
2592 ret = alloc_chrdev_region(&mtd_master_devt, 0, MTD_MASTER_DEVS, "mtd_master");
2593 if (ret < 0) {
2594 pr_err("unable to allocate char dev region\n");
2595 goto err_chrdev;
2596 }
2597
2598 mtd_bdi = mtd_bdi_init("mtd");2533 mtd_bdi = mtd_bdi_init("mtd");
2599 if (IS_ERR(mtd_bdi)) {2534 if (IS_ERR(mtd_bdi)) {
2600 ret = PTR_ERR(mtd_bdi);2535 ret = PTR_ERR(mtd_bdi);
@@ -2619,10 +2554,6 @@ out_procfs: · 18 unmodified lines
2619 bdi_unregister(mtd_bdi);2554 bdi_unregister(mtd_bdi);
2620 bdi_put(mtd_bdi);2555 bdi_put(mtd_bdi);
2621err_bdi:2556err_bdi:
2622 unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS);
2623err_chrdev:
2624 class_unregister(&mtd_master_class);
2625err_reg2:
2626 class_unregister(&mtd_class);2557 class_unregister(&mtd_class);
2627err_reg:2558err_reg:
2628 pr_err("Error registering mtd class or bdi: %d\n", ret);2559 pr_err("Error registering mtd class or bdi: %d\n", ret);
@@ -2636,12 +2567,9 @@ static void __exit cleanup_mtd(void) · 7 unmodified lines
2636 if (proc_mtd)2567 if (proc_mtd)
2637 remove_proc_entry("mtd", NULL);2568 remove_proc_entry("mtd", NULL);
2638 class_unregister(&mtd_class);2569 class_unregister(&mtd_class);
2639 class_unregister(&mtd_master_class);
2640 unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS);
2641 bdi_unregister(mtd_bdi);2570 bdi_unregister(mtd_bdi);
2642 bdi_put(mtd_bdi);2571 bdi_put(mtd_bdi);
2643 idr_destroy(&mtd_idr);2572 idr_destroy(&mtd_idr);
2644 idr_destroy(&mtd_master_idr);
2645}2573}
2646 2574
2647module_init(init_mtd);2575module_init(init_mtd);
drivers/mtd/mtdcore.h+1−1
@@ -8,7 +8,7 @@ extern struct mutex mtd_table_mutex; · 7 unmodified lines
8extern struct backing_dev_info *mtd_bdi;8extern struct backing_dev_info *mtd_bdi;
9 9
10struct mtd_info *__mtd_next_device(int i);10struct mtd_info *__mtd_next_device(int i);
11int __must_check add_mtd_device(struct mtd_info *mtd, bool partitioned);11int __must_check add_mtd_device(struct mtd_info *mtd);
12int del_mtd_device(struct mtd_info *mtd);12int del_mtd_device(struct mtd_info *mtd);
13int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);13int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
14int del_mtd_partitions(struct mtd_info *);14int del_mtd_partitions(struct mtd_info *);
drivers/mtd/mtdpart.c+8−8
@@ -86,7 +86,8 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, · 85 unmodified lines
86 * parent conditional on that option. Note, this is a way to86 * parent conditional on that option. Note, this is a way to
87 * distinguish between the parent and its partitions in sysfs.87 * distinguish between the parent and its partitions in sysfs.
88 */88 */
89 child->dev.parent = &parent->dev;89 child->dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd_is_partition(parent) ?
90 &parent->dev : parent->dev.parent;
90 child->dev.of_node = part->of_node;91 child->dev.of_node = part->of_node;
91 child->parent = parent;92 child->parent = parent;
92 child->part.offset = part->offset;93 child->part.offset = part->offset;
@@ -242,7 +243,7 @@ static int mtd_add_partition_attrs(struct mtd_info *new) · 149 unmodified lines
242}243}
243 244
244int mtd_add_partition(struct mtd_info *parent, const char *name,245int mtd_add_partition(struct mtd_info *parent, const char *name,
245 long long offset, long long length, struct mtd_info **out)246 long long offset, long long length)
246{247{
247 struct mtd_info *master = mtd_get_master(parent);248 struct mtd_info *master = mtd_get_master(parent);
248 u64 parent_size = mtd_is_partition(parent) ?249 u64 parent_size = mtd_is_partition(parent) ?
@@ -275,15 +276,12 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, · 26 unmodified lines
275 list_add_tail(&child->part.node, &parent->partitions);276 list_add_tail(&child->part.node, &parent->partitions);
276 mutex_unlock(&master->master.partitions_lock);277 mutex_unlock(&master->master.partitions_lock);
277 278
278 ret = add_mtd_device(child, true);279 ret = add_mtd_device(child);
279 if (ret)280 if (ret)
280 goto err_remove_part;281 goto err_remove_part;
281 282
282 mtd_add_partition_attrs(child);283 mtd_add_partition_attrs(child);
283 284
284 if (out)
285 *out = child;
286
287 return 0;285 return 0;
288 286
289err_remove_part:287err_remove_part:
@@ -415,7 +413,7 @@ int add_mtd_partitions(struct mtd_info *parent, · 125 unmodified lines
415 list_add_tail(&child->part.node, &parent->partitions);413 list_add_tail(&child->part.node, &parent->partitions);
416 mutex_unlock(&master->master.partitions_lock);414 mutex_unlock(&master->master.partitions_lock);
417 415
418 ret = add_mtd_device(child, true);416 ret = add_mtd_device(child);
419 if (ret) {417 if (ret) {
420 mutex_lock(&master->master.partitions_lock);418 mutex_lock(&master->master.partitions_lock);
421 list_del(&child->part.node);419 list_del(&child->part.node);
@@ -592,6 +590,9 @@ static int mtd_part_of_parse(struct mtd_info *master, · 170 unmodified lines
592 int ret, err = 0;590 int ret, err = 0;
593 591
594 dev = &master->dev;592 dev = &master->dev;
593 /* Use parent device (controller) if the top level MTD is not registered */
594 if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) && !mtd_is_partition(master))
595 dev = master->dev.parent;
595 596
596 np = mtd_get_of_node(master);597 np = mtd_get_of_node(master);
597 if (mtd_is_partition(master))598 if (mtd_is_partition(master))
@@ -710,7 +711,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, · 112 unmodified lines
710 if (ret < 0 && !err)711 if (ret < 0 && !err)
711 err = ret;712 err = ret;
712 }713 }
713
714 return err;714 return err;
715}715}
716 716
include/linux/mtd/partitions.h+1−1
@@ -108,7 +108,7 @@ extern void deregister_mtd_parser(struct mtd_part_parser *parser); · 107 unmodified lines
108 deregister_mtd_parser)108 deregister_mtd_parser)
109 109
110int mtd_add_partition(struct mtd_info *master, const char *name,110int mtd_add_partition(struct mtd_info *master, const char *name,
111 long long offset, long long length, struct mtd_info **part);111 long long offset, long long length);
112int mtd_del_partition(struct mtd_info *master, int partno);112int mtd_del_partition(struct mtd_info *master, int partno);
113uint64_t mtd_get_device_size(const struct mtd_info *mtd);113uint64_t mtd_get_device_size(const struct mtd_info *mtd);
114 114