mtdcore.c (2f98e686ef59b5d19af5847d755798e2031bee3a) | mtdcore.c (19bfa9ebebb5ec0695def57eb1d80de7e9cab369) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Core registration and callback routines for MTD 4 * drivers and users. 5 * 6 * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> 7 * Copyright © 2006 Red Hat UK Limited 8 */ --- 79 unchanged lines hidden (view full) --- 88/* REVISIT once MTD uses the driver model better, whoever allocates 89 * the mtd_info will probably want to use the release() hook... 90 */ 91static void mtd_release(struct device *dev) 92{ 93 struct mtd_info *mtd = dev_get_drvdata(dev); 94 dev_t index = MTD_DEVT(mtd->index); 95 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Core registration and callback routines for MTD 4 * drivers and users. 5 * 6 * Copyright © 1999-2010 David Woodhouse <dwmw2@infradead.org> 7 * Copyright © 2006 Red Hat UK Limited 8 */ --- 79 unchanged lines hidden (view full) --- 88/* REVISIT once MTD uses the driver model better, whoever allocates 89 * the mtd_info will probably want to use the release() hook... 90 */ 91static void mtd_release(struct device *dev) 92{ 93 struct mtd_info *mtd = dev_get_drvdata(dev); 94 dev_t index = MTD_DEVT(mtd->index); 95 |
96 if (mtd_is_partition(mtd)) 97 release_mtd_partition(mtd); 98 |
|
96 /* remove /dev/mtdXro node */ 97 device_destroy(&mtd_class, index + 1); 98} 99 | 99 /* remove /dev/mtdXro node */ 100 device_destroy(&mtd_class, index + 1); 101} 102 |
103static void mtd_device_release(struct kref *kref) 104{ 105 struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt); 106 107 debugfs_remove_recursive(mtd->dbg.dfs_dir); 108 109 /* Try to remove the NVMEM provider */ 110 nvmem_unregister(mtd->nvmem); 111 112 device_unregister(&mtd->dev); 113 114 /* Clear dev so mtd can be safely re-registered later if desired */ 115 memset(&mtd->dev, 0, sizeof(mtd->dev)); 116 117 idr_remove(&mtd_idr, mtd->index); 118 of_node_put(mtd_get_of_node(mtd)); 119 120 module_put(THIS_MODULE); 121} 122 |
|
100#define MTD_DEVICE_ATTR_RO(name) \ 101static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL) 102 103#define MTD_DEVICE_ATTR_RW(name) \ 104static DEVICE_ATTR(name, 0644, mtd_##name##_show, mtd_##name##_store) 105 106static ssize_t mtd_type_show(struct device *dev, 107 struct device_attribute *attr, char *buf) --- 553 unchanged lines hidden (view full) --- 661 else 662 i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); 663 if (i < 0) { 664 error = i; 665 goto fail_locked; 666 } 667 668 mtd->index = i; | 123#define MTD_DEVICE_ATTR_RO(name) \ 124static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL) 125 126#define MTD_DEVICE_ATTR_RW(name) \ 127static DEVICE_ATTR(name, 0644, mtd_##name##_show, mtd_##name##_store) 128 129static ssize_t mtd_type_show(struct device *dev, 130 struct device_attribute *attr, char *buf) --- 553 unchanged lines hidden (view full) --- 684 else 685 i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); 686 if (i < 0) { 687 error = i; 688 goto fail_locked; 689 } 690 691 mtd->index = i; |
669 mtd->usecount = 0; | 692 kref_init(&mtd->refcnt); |
670 671 /* default value if not set by driver */ 672 if (mtd->bitflip_threshold == 0) 673 mtd->bitflip_threshold = mtd->ecc_strength; 674 675 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { 676 int ngroups = mtd_pairing_groups(master); 677 --- 96 unchanged lines hidden (view full) --- 774 * Returns zero on success or 1 on failure, which currently will happen 775 * if the requested device does not appear to be present in the list. 776 */ 777 778int del_mtd_device(struct mtd_info *mtd) 779{ 780 int ret; 781 struct mtd_notifier *not; | 693 694 /* default value if not set by driver */ 695 if (mtd->bitflip_threshold == 0) 696 mtd->bitflip_threshold = mtd->ecc_strength; 697 698 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { 699 int ngroups = mtd_pairing_groups(master); 700 --- 96 unchanged lines hidden (view full) --- 797 * Returns zero on success or 1 on failure, which currently will happen 798 * if the requested device does not appear to be present in the list. 799 */ 800 801int del_mtd_device(struct mtd_info *mtd) 802{ 803 int ret; 804 struct mtd_notifier *not; |
782 struct device_node *mtd_of_node; | |
783 784 mutex_lock(&mtd_table_mutex); 785 786 if (idr_find(&mtd_idr, mtd->index) != mtd) { 787 ret = -ENODEV; 788 goto out_error; 789 } 790 791 /* No need to get a refcount on the module containing 792 the notifier, since we hold the mtd_table_mutex */ 793 list_for_each_entry(not, &mtd_notifiers, list) 794 not->remove(mtd); 795 | 805 806 mutex_lock(&mtd_table_mutex); 807 808 if (idr_find(&mtd_idr, mtd->index) != mtd) { 809 ret = -ENODEV; 810 goto out_error; 811 } 812 813 /* No need to get a refcount on the module containing 814 the notifier, since we hold the mtd_table_mutex */ 815 list_for_each_entry(not, &mtd_notifiers, list) 816 not->remove(mtd); 817 |
796 if (mtd->usecount) { 797 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", 798 mtd->index, mtd->name, mtd->usecount); 799 ret = -EBUSY; 800 } else { 801 mtd_of_node = mtd_get_of_node(mtd); 802 debugfs_remove_recursive(mtd->dbg.dfs_dir); | 818 kref_put(&mtd->refcnt, mtd_device_release); 819 ret = 0; |
803 | 820 |
804 /* Try to remove the NVMEM provider */ 805 nvmem_unregister(mtd->nvmem); 806 807 device_unregister(&mtd->dev); 808 809 /* Clear dev so mtd can be safely re-registered later if desired */ 810 memset(&mtd->dev, 0, sizeof(mtd->dev)); 811 812 idr_remove(&mtd_idr, mtd->index); 813 of_node_put(mtd_of_node); 814 815 module_put(THIS_MODULE); 816 ret = 0; 817 } 818 | |
819out_error: 820 mutex_unlock(&mtd_table_mutex); 821 return ret; 822} 823 824/* 825 * Set a few defaults based on the parent devices, if not provided by the 826 * driver --- 398 unchanged lines hidden (view full) --- 1225int __get_mtd_device(struct mtd_info *mtd) 1226{ 1227 struct mtd_info *master = mtd_get_master(mtd); 1228 int err; 1229 1230 if (!try_module_get(master->owner)) 1231 return -ENODEV; 1232 | 821out_error: 822 mutex_unlock(&mtd_table_mutex); 823 return ret; 824} 825 826/* 827 * Set a few defaults based on the parent devices, if not provided by the 828 * driver --- 398 unchanged lines hidden (view full) --- 1227int __get_mtd_device(struct mtd_info *mtd) 1228{ 1229 struct mtd_info *master = mtd_get_master(mtd); 1230 int err; 1231 1232 if (!try_module_get(master->owner)) 1233 return -ENODEV; 1234 |
1235 kref_get(&mtd->refcnt); 1236 |
|
1233 if (master->_get_device) { 1234 err = master->_get_device(mtd); 1235 1236 if (err) { | 1237 if (master->_get_device) { 1238 err = master->_get_device(mtd); 1239 1240 if (err) { |
1241 kref_put(&mtd->refcnt, mtd_device_release); |
|
1237 module_put(master->owner); 1238 return err; 1239 } 1240 } 1241 | 1242 module_put(master->owner); 1243 return err; 1244 } 1245 } 1246 |
1242 master->usecount++; 1243 | |
1244 while (mtd->parent) { | 1247 while (mtd->parent) { |
1245 mtd->usecount++; | 1248 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd->parent != master) 1249 kref_get(&mtd->parent->refcnt); |
1246 mtd = mtd->parent; 1247 } 1248 1249 return 0; 1250} 1251EXPORT_SYMBOL_GPL(__get_mtd_device); 1252 1253/** --- 70 unchanged lines hidden (view full) --- 1324 1325} 1326EXPORT_SYMBOL_GPL(put_mtd_device); 1327 1328void __put_mtd_device(struct mtd_info *mtd) 1329{ 1330 struct mtd_info *master = mtd_get_master(mtd); 1331 | 1250 mtd = mtd->parent; 1251 } 1252 1253 return 0; 1254} 1255EXPORT_SYMBOL_GPL(__get_mtd_device); 1256 1257/** --- 70 unchanged lines hidden (view full) --- 1328 1329} 1330EXPORT_SYMBOL_GPL(put_mtd_device); 1331 1332void __put_mtd_device(struct mtd_info *mtd) 1333{ 1334 struct mtd_info *master = mtd_get_master(mtd); 1335 |
1332 while (mtd->parent) { 1333 --mtd->usecount; 1334 BUG_ON(mtd->usecount < 0); 1335 mtd = mtd->parent; | 1336 while (mtd != master) { 1337 struct mtd_info *parent = mtd->parent; 1338 1339 kref_put(&mtd->refcnt, mtd_device_release); 1340 mtd = parent; |
1336 } 1337 | 1341 } 1342 |
1338 master->usecount--; 1339 | |
1340 if (master->_put_device) 1341 master->_put_device(master); 1342 1343 module_put(master->owner); | 1343 if (master->_put_device) 1344 master->_put_device(master); 1345 1346 module_put(master->owner); |
1347 1348 if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) 1349 kref_put(&master->refcnt, mtd_device_release); |
|
1344} 1345EXPORT_SYMBOL_GPL(__put_mtd_device); 1346 1347/* 1348 * Erase is an synchronous operation. Device drivers are epected to return a 1349 * negative error code if the operation failed and update instr->fail_addr 1350 * to point the portion that was not properly erased. 1351 */ --- 1194 unchanged lines hidden --- | 1350} 1351EXPORT_SYMBOL_GPL(__put_mtd_device); 1352 1353/* 1354 * Erase is an synchronous operation. Device drivers are epected to return a 1355 * negative error code if the operation failed and update instr->fail_addr 1356 * to point the portion that was not properly erased. 1357 */ --- 1194 unchanged lines hidden --- |