| @@ -68,13 +68,7 @@ static struct class mtd_class = { · 67 unmodified lines |
| 68 | 68 | .pm = MTD_CLS_PM_OPS, |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | | −static struct class mtd_master_class = { |
| 72 | | − .name = "mtd_master", |
| 73 | | − .pm = MTD_CLS_PM_OPS, |
| 74 | | −}; |
| 75 | | − |
| 76 | 71 | static DEFINE_IDR(mtd_idr); |
| 77 | | −static DEFINE_IDR(mtd_master_idr); |
| 78 | 72 | |
| 79 | 73 | /* These are exported solely for the purpose of mtd_blkdevs.c. You |
| 80 | 74 | should not use them for _anything_ else */ |
| @@ -89,9 +83,8 @@ EXPORT_SYMBOL_GPL(__mtd_next_device); · 8 unmodified lines |
| 89 | 83 | |
| 90 | 84 | static LIST_HEAD(mtd_notifiers); |
| 91 | 85 | |
| 92 | | −#define MTD_MASTER_DEVS 255 |
| 86 | + |
| 93 | 87 | #define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2) |
| 94 | | −static dev_t mtd_master_devt; |
| 95 | 88 | |
| 96 | 89 | /* REVISIT once MTD uses the driver model better, whoever allocates |
| 97 | 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 | 104 | device_destroy(&mtd_class, index + 1); |
| 112 | 105 | } |
| 113 | 106 | |
| 114 | | −static 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 | | − |
| 125 | 107 | static void mtd_device_release(struct kref *kref) |
| 126 | 108 | { |
| 127 | 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 | 367 | .release = mtd_release, |
| 386 | 368 | }; |
| 387 | 369 | |
| 388 | | −static const struct device_type mtd_master_devtype = { |
| 389 | | − .name = "mtd_master", |
| 390 | | − .release = mtd_master_release, |
| 391 | | −}; |
| 392 | | − |
| 393 | 370 | static bool mtd_expert_analysis_mode; |
| 394 | 371 | |
| 395 | 372 | #ifdef CONFIG_DEBUG_FS |
| @@ -657,13 +634,13 @@ exit_parent: · 261 unmodified lines |
| 657 | 634 | /** |
| 658 | 635 | * add_mtd_device - register an MTD device |
| 659 | 636 | * @mtd: pointer to new MTD device info structure |
| 660 | | − * @partitioned: create partitioned device |
| 661 | 637 | * |
| 662 | 638 | * Add a device to the list of MTD devices present in the system, and |
| 663 | 639 | * notify each currently active MTD 'user' of its arrival. Returns |
| 664 | 640 | * zero on success or non-zero on failure. |
| 665 | 641 | */ |
| 666 | | −int add_mtd_device(struct mtd_info *mtd, bool partitioned) |
| 642 | + |
| 643 | +int add_mtd_device(struct mtd_info *mtd) |
| 667 | 644 | { |
| 668 | 645 | struct device_node *np = mtd_get_of_node(mtd); |
| 669 | 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 | 687 | ofidx = -1; |
| 711 | 688 | if (np) |
| 712 | 689 | ofidx = of_alias_get_id(np, "mtd"); |
| 713 | | − if (partitioned) { |
| 714 | | − if (ofidx >= 0) |
| 715 | | − i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL); |
| 716 | | − else |
| 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 | | − } |
| 690 | + if (ofidx >= 0) |
| 691 | + i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL); |
| 692 | + else |
| 693 | + i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); |
| 724 | 694 | if (i < 0) { |
| 725 | 695 | error = i; |
| 726 | 696 | goto fail_locked; |
| @@ -768,18 +738,10 @@ int add_mtd_device(struct mtd_info *mtd, bool partitioned) · 41 unmodified lines |
| 768 | 738 | /* Caller should have set dev.parent to match the |
| 769 | 739 | * physical device, if appropriate. |
| 770 | 740 | */ |
| 771 | | − if (partitioned) { |
| 772 | | − mtd->dev.type = &mtd_devtype; |
| 773 | | − mtd->dev.class = &mtd_class; |
| 774 | | − mtd->dev.devt = MTD_DEVT(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 | | − } |
| 741 | + mtd->dev.type = &mtd_devtype; |
| 742 | + mtd->dev.class = &mtd_class; |
| 743 | + mtd->dev.devt = MTD_DEVT(i); |
| 744 | + error = dev_set_name(&mtd->dev, "mtd%d", i); |
| 783 | 745 | if (error) |
| 784 | 746 | goto fail_devname; |
| 785 | 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 | 749 | of_node_get(mtd_get_of_node(mtd)); |
| 788 | 750 | error = device_register(&mtd->dev); |
| 789 | 751 | if (error) { |
| 790 | | − pr_err("mtd: %s device_register fail %d\n", mtd->name, error); |
| 791 | 752 | put_device(&mtd->dev); |
| 792 | 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 | 761 | mtd_debugfs_populate(mtd); |
| 801 | 762 | |
| 802 | | − if (partitioned) { |
| 803 | | − device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, |
| 804 | | − "mtd%dro", i); |
| 805 | | − } |
| 763 | + device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, |
| 764 | + "mtd%dro", i); |
| 806 | 765 | |
| 807 | | − pr_debug("mtd: Giving out %spartitioned device %d to %s\n", |
| 808 | | − partitioned ? "" : "un-", i, mtd->name); |
| 766 | + pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name); |
| 809 | 767 | /* No need to get a refcount on the module containing |
| 810 | 768 | the notifier, since we hold the mtd_table_mutex */ |
| 811 | 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 | 772 | mutex_unlock(&mtd_table_mutex); |
| 815 | 773 | |
| 816 | | − if (partitioned) { |
| 817 | | − if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) { |
| 818 | | − if (IS_BUILTIN(CONFIG_MTD)) { |
| 819 | | − pr_info("mtd: setting mtd%d (%s) as root device\n", |
| 820 | | − mtd->index, mtd->name); |
| 821 | | − ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); |
| 822 | | − } else { |
| 823 | | − pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", |
| 824 | | − mtd->index, mtd->name); |
| 825 | | − } |
| 774 | + if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) { |
| 775 | + if (IS_BUILTIN(CONFIG_MTD)) { |
| 776 | + pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); |
| 777 | + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); |
| 778 | + } else { |
| 779 | + pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", |
| 780 | + mtd->index, mtd->name); |
| 826 | 781 | } |
| 827 | 782 | } |
| 828 | 783 | |
| @@ -838,10 +793,7 @@ fail_nvmem_add: · 9 unmodified lines |
| 838 | 793 | fail_added: |
| 839 | 794 | of_node_put(mtd_get_of_node(mtd)); |
| 840 | 795 | fail_devname: |
| 841 | | − if (partitioned) |
| 842 | | − idr_remove(&mtd_idr, i); |
| 843 | | − else |
| 844 | | − idr_remove(&mtd_master_idr, i); |
| 796 | + idr_remove(&mtd_idr, i); |
| 845 | 797 | fail_locked: |
| 846 | 798 | mutex_unlock(&mtd_table_mutex); |
| 847 | 799 | return error; |
| @@ -859,14 +811,12 @@ fail_locked: · 11 unmodified lines |
| 859 | 811 | |
| 860 | 812 | int del_mtd_device(struct mtd_info *mtd) |
| 861 | 813 | { |
| 862 | | − struct mtd_notifier *not; |
| 863 | | − struct idr *idr; |
| 864 | 814 | int ret; |
| 815 | + struct mtd_notifier *not; |
| 865 | 816 | |
| 866 | 817 | mutex_lock(&mtd_table_mutex); |
| 867 | 818 | |
| 868 | | − idr = mtd->dev.class == &mtd_class ? &mtd_idr : &mtd_master_idr; |
| 869 | | − if (idr_find(idr, mtd->index) != mtd) { |
| 819 | + if (idr_find(&mtd_idr, mtd->index) != mtd) { |
| 870 | 820 | ret = -ENODEV; |
| 871 | 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 | 1056 | const struct mtd_partition *parts, |
| 1107 | 1057 | int nr_parts) |
| 1108 | 1058 | { |
| 1109 | | − struct mtd_info *parent; |
| 1110 | 1059 | int ret, err; |
| 1111 | 1060 | |
| 1112 | 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 | 1064 | if (ret) |
| 1116 | 1065 | goto out; |
| 1117 | 1066 | |
| 1118 | | − ret = add_mtd_device(mtd, false); |
| 1119 | | − if (ret) |
| 1120 | | − goto out; |
| 1121 | | − |
| 1122 | 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 | 1069 | if (ret) |
| 1125 | 1070 | goto out; |
| 1126 | | − |
| 1127 | | − } else { |
| 1128 | | − parent = mtd; |
| 1129 | 1071 | } |
| 1130 | 1072 | |
| 1131 | 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 | 1075 | if (ret == -EPROBE_DEFER) |
| 1134 | 1076 | goto out; |
| 1135 | 1077 | |
| 1136 | 1078 | if (ret > 0) |
| 1137 | 1079 | ret = 0; |
| 1138 | 1080 | else if (nr_parts) |
| 1139 | | − ret = add_mtd_partitions(parent, parts, nr_parts); |
| 1140 | | − else if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) |
| 1141 | | − ret = mtd_add_partition(parent, mtd->name, 0, MTDPART_SIZ_FULL, NULL); |
| 1081 | + ret = add_mtd_partitions(mtd, parts, nr_parts); |
| 1082 | + else if (!device_is_registered(&mtd->dev)) |
| 1083 | + ret = add_mtd_device(mtd); |
| 1084 | + else |
| 1085 | + ret = 0; |
| 1142 | 1086 | |
| 1143 | 1087 | if (ret) |
| 1144 | 1088 | goto out; |
| @@ -1158,14 +1102,13 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, · 13 unmodified lines |
| 1158 | 1102 | register_reboot_notifier(&mtd->reboot_notifier); |
| 1159 | 1103 | } |
| 1160 | 1104 | |
| 1161 | | − return 0; |
| 1162 | 1105 | out: |
| 1163 | | − nvmem_unregister(mtd->otp_user_nvmem); |
| 1164 | | − nvmem_unregister(mtd->otp_factory_nvmem); |
| 1165 | | − |
| 1166 | | − del_mtd_partitions(mtd); |
| 1106 | + if (ret) { |
| 1107 | + nvmem_unregister(mtd->otp_user_nvmem); |
| 1108 | + nvmem_unregister(mtd->otp_factory_nvmem); |
| 1109 | + } |
| 1167 | 1110 | |
| 1168 | | − if (device_is_registered(&mtd->dev)) { |
| 1111 | + if (ret && device_is_registered(&mtd->dev)) { |
| 1169 | 1112 | err = del_mtd_device(mtd); |
| 1170 | 1113 | if (err) |
| 1171 | 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 | 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 | 1273 | return 0; |
| 1330 | 1274 | } |
| @@ -1418,7 +1362,8 @@ void __put_mtd_device(struct mtd_info *mtd) · 87 unmodified lines |
| 1418 | 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 | 1368 | module_put(master->owner); |
| 1424 | 1369 | |
| @@ -2585,16 +2530,6 @@ static int __init init_mtd(void) · 1160 unmodified lines |
| 2585 | 2530 | if (ret) |
| 2586 | 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 | 2533 | mtd_bdi = mtd_bdi_init("mtd"); |
| 2599 | 2534 | if (IS_ERR(mtd_bdi)) { |
| 2600 | 2535 | ret = PTR_ERR(mtd_bdi); |
| @@ -2619,10 +2554,6 @@ out_procfs: · 18 unmodified lines |
| 2619 | 2554 | bdi_unregister(mtd_bdi); |
| 2620 | 2555 | bdi_put(mtd_bdi); |
| 2621 | 2556 | err_bdi: |
| 2622 | | − unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS); |
| 2623 | | −err_chrdev: |
| 2624 | | − class_unregister(&mtd_master_class); |
| 2625 | | −err_reg2: |
| 2626 | 2557 | class_unregister(&mtd_class); |
| 2627 | 2558 | err_reg: |
| 2628 | 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 | 2567 | if (proc_mtd) |
| 2637 | 2568 | remove_proc_entry("mtd", NULL); |
| 2638 | 2569 | class_unregister(&mtd_class); |
| 2639 | | − class_unregister(&mtd_master_class); |
| 2640 | | − unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS); |
| 2641 | 2570 | bdi_unregister(mtd_bdi); |
| 2642 | 2571 | bdi_put(mtd_bdi); |
| 2643 | 2572 | idr_destroy(&mtd_idr); |
| 2644 | | − idr_destroy(&mtd_master_idr); |
| 2645 | 2573 | } |
| 2646 | 2574 | |
| 2647 | 2575 | module_init(init_mtd); |