diff options
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 @@ | |||
38 | #include <linux/gfp.h> | 38 | #include <linux/gfp.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/reboot.h> | 40 | #include <linux/reboot.h> |
41 | #include <linux/kconfig.h> | ||
41 | 42 | ||
42 | #include <linux/mtd/mtd.h> | 43 | #include <linux/mtd/mtd.h> |
43 | #include <linux/mtd/partitions.h> | 44 | #include <linux/mtd/partitions.h> |
@@ -501,6 +502,29 @@ out_error: | |||
501 | return ret; | 502 | return ret; |
502 | } | 503 | } |
503 | 504 | ||
505 | static int mtd_add_device_partitions(struct mtd_info *mtd, | ||
506 | struct mtd_partition *real_parts, | ||
507 | int nbparts) | ||
508 | { | ||
509 | int ret; | ||
510 | |||
511 | if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { | ||
512 | ret = add_mtd_device(mtd); | ||
513 | if (ret == 1) | ||
514 | return -ENODEV; | ||
515 | } | ||
516 | |||
517 | if (nbparts > 0) { | ||
518 | ret = add_mtd_partitions(mtd, real_parts, nbparts); | ||
519 | if (ret && IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) | ||
520 | del_mtd_device(mtd); | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | |||
504 | /** | 528 | /** |
505 | * mtd_device_parse_register - parse partitions and register an MTD device. | 529 | * mtd_device_parse_register - parse partitions and register an MTD device. |
506 | * | 530 | * |
@@ -523,7 +547,8 @@ out_error: | |||
523 | * found this functions tries to fallback to information specified in | 547 | * found this functions tries to fallback to information specified in |
524 | * @parts/@nr_parts. | 548 | * @parts/@nr_parts. |
525 | * * If any partitioning info was found, this function registers the found | 549 | * * If any partitioning info was found, this function registers the found |
526 | * partitions. | 550 | * partitions. If the MTD_PARTITIONED_MASTER option is set, then the device |
551 | * as a whole is registered first. | ||
527 | * * If no partitions were found this function just registers the MTD device | 552 | * * If no partitions were found this function just registers the MTD device |
528 | * @mtd and exits. | 553 | * @mtd and exits. |
529 | * | 554 | * |
@@ -534,27 +559,21 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
534 | const struct mtd_partition *parts, | 559 | const struct mtd_partition *parts, |
535 | int nr_parts) | 560 | int nr_parts) |
536 | { | 561 | { |
537 | int err; | 562 | int ret; |
538 | struct mtd_partition *real_parts; | 563 | struct mtd_partition *real_parts = NULL; |
539 | 564 | ||
540 | err = parse_mtd_partitions(mtd, types, &real_parts, parser_data); | 565 | ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); |
541 | if (err <= 0 && nr_parts && parts) { | 566 | if (ret <= 0 && nr_parts && parts) { |
542 | real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, | 567 | real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, |
543 | GFP_KERNEL); | 568 | GFP_KERNEL); |
544 | if (!real_parts) | 569 | if (!real_parts) |
545 | err = -ENOMEM; | 570 | ret = -ENOMEM; |
546 | else | 571 | else |
547 | err = nr_parts; | 572 | ret = nr_parts; |
548 | } | 573 | } |
549 | 574 | ||
550 | if (err > 0) { | 575 | if (ret >= 0) |
551 | err = add_mtd_partitions(mtd, real_parts, err); | 576 | ret = mtd_add_device_partitions(mtd, real_parts, ret); |
552 | kfree(real_parts); | ||
553 | } else if (err == 0) { | ||
554 | err = add_mtd_device(mtd); | ||
555 | if (err == 1) | ||
556 | err = -ENODEV; | ||
557 | } | ||
558 | 577 | ||
559 | /* | 578 | /* |
560 | * FIXME: some drivers unfortunately call this function more than once. | 579 | * 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, | |||
569 | register_reboot_notifier(&mtd->reboot_notifier); | 588 | register_reboot_notifier(&mtd->reboot_notifier); |
570 | } | 589 | } |
571 | 590 | ||
572 | return err; | 591 | kfree(real_parts); |
592 | return ret; | ||
573 | } | 593 | } |
574 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); | 594 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); |
575 | 595 | ||