@@ -93,10 +93,33 @@ static void mtd_release(struct device *dev)
93
93
struct mtd_info * mtd = dev_get_drvdata (dev );
94
94
dev_t index = MTD_DEVT (mtd -> index );
95
95
96
+ if (mtd_is_partition (mtd ))
97
+ release_mtd_partition (mtd );
98
+
96
99
/* remove /dev/mtdXro node */
97
100
device_destroy (& mtd_class , index + 1 );
98
101
}
99
102
103
+ static 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
123
#define MTD_DEVICE_ATTR_RO (name ) \
101
124
static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL)
102
125
@@ -666,7 +689,7 @@ int add_mtd_device(struct mtd_info *mtd)
666
689
}
667
690
668
691
mtd -> index = i ;
669
- mtd -> usecount = 0 ;
692
+ kref_init ( & mtd -> refcnt ) ;
670
693
671
694
/* default value if not set by driver */
672
695
if (mtd -> bitflip_threshold == 0 )
@@ -779,7 +802,6 @@ int del_mtd_device(struct mtd_info *mtd)
779
802
{
780
803
int ret ;
781
804
struct mtd_notifier * not ;
782
- struct device_node * mtd_of_node ;
783
805
784
806
mutex_lock (& mtd_table_mutex );
785
807
@@ -793,28 +815,8 @@ int del_mtd_device(struct mtd_info *mtd)
793
815
list_for_each_entry (not , & mtd_notifiers , list )
794
816
not -> remove (mtd );
795
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 );
803
-
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
+ kref_put (& mtd -> refcnt , mtd_device_release );
819
+ ret = 0 ;
818
820
819
821
out_error :
820
822
mutex_unlock (& mtd_table_mutex );
@@ -1230,19 +1232,21 @@ int __get_mtd_device(struct mtd_info *mtd)
1230
1232
if (!try_module_get (master -> owner ))
1231
1233
return - ENODEV ;
1232
1234
1235
+ kref_get (& mtd -> refcnt );
1236
+
1233
1237
if (master -> _get_device ) {
1234
1238
err = master -> _get_device (mtd );
1235
1239
1236
1240
if (err ) {
1241
+ kref_put (& mtd -> refcnt , mtd_device_release );
1237
1242
module_put (master -> owner );
1238
1243
return err ;
1239
1244
}
1240
1245
}
1241
1246
1242
- master -> usecount ++ ;
1243
-
1244
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
1250
mtd = mtd -> parent ;
1247
1251
}
1248
1252
@@ -1329,18 +1333,20 @@ void __put_mtd_device(struct mtd_info *mtd)
1329
1333
{
1330
1334
struct mtd_info * master = mtd_get_master (mtd );
1331
1335
1332
- while (mtd -> parent ) {
1333
- -- mtd -> usecount ;
1334
- BUG_ON (mtd -> usecount < 0 );
1335
- mtd = mtd -> parent ;
1336
- }
1336
+ while (mtd != master ) {
1337
+ struct mtd_info * parent = mtd -> parent ;
1337
1338
1338
- master -> usecount -- ;
1339
+ kref_put (& mtd -> refcnt , mtd_device_release );
1340
+ mtd = parent ;
1341
+ }
1339
1342
1340
1343
if (master -> _put_device )
1341
1344
master -> _put_device (master );
1342
1345
1343
1346
module_put (master -> owner );
1347
+
1348
+ if (IS_ENABLED (CONFIG_MTD_PARTITIONED_MASTER ))
1349
+ kref_put (& master -> refcnt , mtd_device_release );
1344
1350
}
1345
1351
EXPORT_SYMBOL_GPL (__put_mtd_device );
1346
1352
0 commit comments