@@ -93,10 +93,33 @@ static void mtd_release(struct device *dev)
9393 struct mtd_info * mtd = dev_get_drvdata (dev );
9494 dev_t index = MTD_DEVT (mtd -> index );
9595
96+ if (mtd_is_partition (mtd ))
97+ release_mtd_partition (mtd );
98+
9699 /* remove /dev/mtdXro node */
97100 device_destroy (& mtd_class , index + 1 );
98101}
99102
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+
100123#define MTD_DEVICE_ATTR_RO (name ) \
101124static DEVICE_ATTR(name, 0444, mtd_##name##_show, NULL)
102125
@@ -666,7 +689,7 @@ int add_mtd_device(struct mtd_info *mtd)
666689 }
667690
668691 mtd -> index = i ;
669- mtd -> usecount = 0 ;
692+ kref_init ( & mtd -> refcnt ) ;
670693
671694 /* default value if not set by driver */
672695 if (mtd -> bitflip_threshold == 0 )
@@ -779,7 +802,6 @@ int del_mtd_device(struct mtd_info *mtd)
779802{
780803 int ret ;
781804 struct mtd_notifier * not ;
782- struct device_node * mtd_of_node ;
783805
784806 mutex_lock (& mtd_table_mutex );
785807
@@ -793,28 +815,8 @@ int del_mtd_device(struct mtd_info *mtd)
793815 list_for_each_entry (not , & mtd_notifiers , list )
794816 not -> remove (mtd );
795817
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 ;
818820
819821out_error :
820822 mutex_unlock (& mtd_table_mutex );
@@ -1230,19 +1232,21 @@ int __get_mtd_device(struct mtd_info *mtd)
12301232 if (!try_module_get (master -> owner ))
12311233 return - ENODEV ;
12321234
1235+ kref_get (& mtd -> refcnt );
1236+
12331237 if (master -> _get_device ) {
12341238 err = master -> _get_device (mtd );
12351239
12361240 if (err ) {
1241+ kref_put (& mtd -> refcnt , mtd_device_release );
12371242 module_put (master -> owner );
12381243 return err ;
12391244 }
12401245 }
12411246
1242- master -> usecount ++ ;
1243-
12441247 while (mtd -> parent ) {
1245- mtd -> usecount ++ ;
1248+ if (IS_ENABLED (CONFIG_MTD_PARTITIONED_MASTER ) || mtd -> parent != master )
1249+ kref_get (& mtd -> parent -> refcnt );
12461250 mtd = mtd -> parent ;
12471251 }
12481252
@@ -1329,18 +1333,20 @@ void __put_mtd_device(struct mtd_info *mtd)
13291333{
13301334 struct mtd_info * master = mtd_get_master (mtd );
13311335
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 ;
13371338
1338- master -> usecount -- ;
1339+ kref_put (& mtd -> refcnt , mtd_device_release );
1340+ mtd = parent ;
1341+ }
13391342
13401343 if (master -> _put_device )
13411344 master -> _put_device (master );
13421345
13431346 module_put (master -> owner );
1347+
1348+ if (IS_ENABLED (CONFIG_MTD_PARTITIONED_MASTER ))
1349+ kref_put (& master -> refcnt , mtd_device_release );
13441350}
13451351EXPORT_SYMBOL_GPL (__put_mtd_device );
13461352
0 commit comments