aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdcore.c
diff options
context:
space:
mode:
authorDan Ehrenberg <dehrenberg@chromium.org>2015-04-02 18:15:10 -0400
committerBrian Norris <computersforpeace@gmail.com>2015-04-05 20:44:01 -0400
commit727dc612c46b8f3858537ea23805b3e897cf127e (patch)
tree5bcda420d5f0071fc8d8c8c02dc68166256323e7 /drivers/mtd/mtdcore.c
parent9cd5196ed25979a3760f97225aae3e17caf21512 (diff)
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 @@
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
505static 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}
574EXPORT_SYMBOL_GPL(mtd_device_parse_register); 594EXPORT_SYMBOL_GPL(mtd_device_parse_register);
575 595