summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/mtdcore.c3
-rw-r--r--drivers/mtd/mtdcore.h2
-rw-r--r--drivers/mtd/mtdpart.c35
-rw-r--r--include/linux/mtd/partitions.h1
4 files changed, 37 insertions, 4 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 20b2b38247b6..89d811e7b04a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -630,8 +630,7 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
630 630
631out: 631out:
632 /* Cleanup any parsed partitions */ 632 /* Cleanup any parsed partitions */
633 if (parsed.parser) 633 mtd_part_parser_cleanup(&parsed);
634 kfree(parsed.parts);
635 return ret; 634 return ret;
636} 635}
637EXPORT_SYMBOL_GPL(mtd_device_parse_register); 636EXPORT_SYMBOL_GPL(mtd_device_parse_register);
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h
index ce81cc2002f4..55fdb8e1fd2a 100644
--- a/drivers/mtd/mtdcore.h
+++ b/drivers/mtd/mtdcore.h
@@ -17,6 +17,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char * const *types,
17 struct mtd_partitions *pparts, 17 struct mtd_partitions *pparts,
18 struct mtd_part_parser_data *data); 18 struct mtd_part_parser_data *data);
19 19
20void mtd_part_parser_cleanup(struct mtd_partitions *parts);
21
20int __init init_mtdchar(void); 22int __init init_mtdchar(void);
21void __exit cleanup_mtdchar(void); 23void __exit cleanup_mtdchar(void);
22 24
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 53517d7653cb..10bf304027dd 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -709,10 +709,23 @@ static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
709 module_put(p->owner); 709 module_put(p->owner);
710} 710}
711 711
712/*
713 * Many partition parsers just expected the core to kfree() all their data in
714 * one chunk. Do that by default.
715 */
716static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts,
717 int nr_parts)
718{
719 kfree(pparts);
720}
721
712int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) 722int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner)
713{ 723{
714 p->owner = owner; 724 p->owner = owner;
715 725
726 if (!p->cleanup)
727 p->cleanup = &mtd_part_parser_cleanup_default;
728
716 spin_lock(&part_parser_lock); 729 spin_lock(&part_parser_lock);
717 list_add(&p->list, &part_parsers); 730 list_add(&p->list, &part_parsers);
718 spin_unlock(&part_parser_lock); 731 spin_unlock(&part_parser_lock);
@@ -756,7 +769,9 @@ static const char * const default_mtd_part_types[] = {
756 * This function may return: 769 * This function may return:
757 * o a negative error code in case of failure 770 * o a negative error code in case of failure
758 * o zero otherwise, and @pparts will describe the partitions, number of 771 * o zero otherwise, and @pparts will describe the partitions, number of
759 * partitions, and the parser which parsed them 772 * partitions, and the parser which parsed them. Caller must release
773 * resources with mtd_part_parser_cleanup() when finished with the returned
774 * data.
760 */ 775 */
761int parse_mtd_partitions(struct mtd_info *master, const char *const *types, 776int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
762 struct mtd_partitions *pparts, 777 struct mtd_partitions *pparts,
@@ -780,7 +795,6 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
780 ret = (*parser->parse_fn)(master, &pparts->parts, data); 795 ret = (*parser->parse_fn)(master, &pparts->parts, data);
781 pr_debug("%s: parser %s: %i\n", 796 pr_debug("%s: parser %s: %i\n",
782 master->name, parser->name, ret); 797 master->name, parser->name, ret);
783 mtd_part_parser_put(parser);
784 if (ret > 0) { 798 if (ret > 0) {
785 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", 799 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
786 ret, parser->name, master->name); 800 ret, parser->name, master->name);
@@ -788,6 +802,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
788 pparts->parser = parser; 802 pparts->parser = parser;
789 return 0; 803 return 0;
790 } 804 }
805 mtd_part_parser_put(parser);
791 /* 806 /*
792 * Stash the first error we see; only report it if no parser 807 * Stash the first error we see; only report it if no parser
793 * succeeds 808 * succeeds
@@ -798,6 +813,22 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
798 return err; 813 return err;
799} 814}
800 815
816void mtd_part_parser_cleanup(struct mtd_partitions *parts)
817{
818 const struct mtd_part_parser *parser;
819
820 if (!parts)
821 return;
822
823 parser = parts->parser;
824 if (parser) {
825 if (parser->cleanup)
826 parser->cleanup(parts->parts, parts->nr_parts);
827
828 mtd_part_parser_put(parser);
829 }
830}
831
801int mtd_is_partition(const struct mtd_info *mtd) 832int mtd_is_partition(const struct mtd_info *mtd)
802{ 833{
803 struct mtd_part *part; 834 struct mtd_part *part;
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index cceaf7bd1537..70736e1e6c8f 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -71,6 +71,7 @@ struct mtd_part_parser {
71 const char *name; 71 const char *name;
72 int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, 72 int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
73 struct mtd_part_parser_data *); 73 struct mtd_part_parser_data *);
74 void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
74}; 75};
75 76
76/* Container for passing around a set of parsed partitions */ 77/* Container for passing around a set of parsed partitions */