19
19
#include <linux/fs.h>
20
20
#include <linux/idr.h>
21
21
#include <linux/init.h>
22
+ #include <linux/kref.h>
22
23
#include <linux/module.h>
23
24
#include <linux/nvmem-consumer.h>
24
25
#include <linux/nvmem-provider.h>
@@ -31,7 +32,7 @@ struct nvmem_device {
31
32
int stride ;
32
33
int word_size ;
33
34
int id ;
34
- int users ;
35
+ struct kref refcnt ;
35
36
size_t size ;
36
37
bool read_only ;
37
38
int flags ;
@@ -463,6 +464,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
463
464
return ERR_PTR (rval );
464
465
}
465
466
467
+ kref_init (& nvmem -> refcnt );
468
+
466
469
nvmem -> id = rval ;
467
470
nvmem -> owner = config -> owner ;
468
471
if (!nvmem -> owner && config -> dev -> driver )
@@ -532,6 +535,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
532
535
}
533
536
EXPORT_SYMBOL_GPL (nvmem_register );
534
537
538
+ static void nvmem_device_release (struct kref * kref )
539
+ {
540
+ struct nvmem_device * nvmem ;
541
+
542
+ nvmem = container_of (kref , struct nvmem_device , refcnt );
543
+
544
+ if (nvmem -> flags & FLAG_COMPAT )
545
+ device_remove_bin_file (nvmem -> base_dev , & nvmem -> eeprom );
546
+
547
+ nvmem_device_remove_all_cells (nvmem );
548
+ device_del (& nvmem -> dev );
549
+ put_device (& nvmem -> dev );
550
+ }
551
+
535
552
/**
536
553
* nvmem_unregister() - Unregister previously registered nvmem device
537
554
*
@@ -541,19 +558,7 @@ EXPORT_SYMBOL_GPL(nvmem_register);
541
558
*/
542
559
int nvmem_unregister (struct nvmem_device * nvmem )
543
560
{
544
- mutex_lock (& nvmem_mutex );
545
- if (nvmem -> users ) {
546
- mutex_unlock (& nvmem_mutex );
547
- return - EBUSY ;
548
- }
549
- mutex_unlock (& nvmem_mutex );
550
-
551
- if (nvmem -> flags & FLAG_COMPAT )
552
- device_remove_bin_file (nvmem -> base_dev , & nvmem -> eeprom );
553
-
554
- nvmem_device_remove_all_cells (nvmem );
555
- device_del (& nvmem -> dev );
556
- put_device (& nvmem -> dev );
561
+ kref_put (& nvmem -> refcnt , nvmem_device_release );
557
562
558
563
return 0 ;
559
564
}
@@ -647,30 +652,25 @@ static struct nvmem_device *__nvmem_device_get(struct device_node *np,
647
652
}
648
653
}
649
654
650
- nvmem -> users ++ ;
651
655
mutex_unlock (& nvmem_mutex );
652
656
653
657
if (!try_module_get (nvmem -> owner )) {
654
658
dev_err (& nvmem -> dev ,
655
659
"could not increase module refcount for cell %s\n" ,
656
660
nvmem_dev_name (nvmem ));
657
661
658
- mutex_lock (& nvmem_mutex );
659
- nvmem -> users -- ;
660
- mutex_unlock (& nvmem_mutex );
661
-
662
662
return ERR_PTR (- EINVAL );
663
663
}
664
664
665
+ kref_get (& nvmem -> refcnt );
666
+
665
667
return nvmem ;
666
668
}
667
669
668
670
static void __nvmem_device_put (struct nvmem_device * nvmem )
669
671
{
670
672
module_put (nvmem -> owner );
671
- mutex_lock (& nvmem_mutex );
672
- nvmem -> users -- ;
673
- mutex_unlock (& nvmem_mutex );
673
+ kref_put (& nvmem -> refcnt , nvmem_device_release );
674
674
}
675
675
676
676
static struct nvmem_device * nvmem_find (const char * name )
0 commit comments