2323#include <linux/reset.h>
2424#include <linux/reset-controller.h>
2525#include <linux/slab.h>
26+ #include <linux/srcu.h>
2627
2728static DEFINE_MUTEX (reset_list_mutex );
2829static LIST_HEAD (reset_controller_list );
@@ -36,6 +37,7 @@ static DEFINE_IDA(reset_gpio_ida);
3637 * struct reset_control - a reset control
3738 * @rcdev: a pointer to the reset controller device
3839 * this reset control belongs to
40+ * @srcu: protects the rcdev pointer from removal during consumer access
3941 * @list: list entry for the rcdev's reset controller list
4042 * @id: ID of the reset controller in the reset
4143 * controller device
@@ -49,7 +51,8 @@ static DEFINE_IDA(reset_gpio_ida);
4951 * will be either 0 or 1.
5052 */
5153struct reset_control {
52- struct reset_controller_dev * rcdev ;
54+ struct reset_controller_dev __rcu * rcdev ;
55+ struct srcu_struct srcu ;
5356 struct list_head list ;
5457 unsigned int id ;
5558 struct kref refcnt ;
@@ -137,15 +140,35 @@ int reset_controller_register(struct reset_controller_dev *rcdev)
137140}
138141EXPORT_SYMBOL_GPL (reset_controller_register );
139142
143+ static void reset_controller_remove (struct reset_controller_dev * rcdev ,
144+ struct reset_control * rstc )
145+ {
146+ list_del (& rstc -> list );
147+ module_put (rcdev -> owner );
148+ put_device (rcdev -> dev );
149+ }
150+
140151/**
141152 * reset_controller_unregister - unregister a reset controller device
142153 * @rcdev: a pointer to the reset controller device
143154 */
144155void reset_controller_unregister (struct reset_controller_dev * rcdev )
145156{
157+ struct reset_control * rstc , * pos ;
158+
146159 guard (mutex )(& reset_list_mutex );
147160
148161 list_del (& rcdev -> list );
162+
163+ /*
164+ * Numb but don't free the remaining reset control handles that are
165+ * still held by consumers.
166+ */
167+ list_for_each_entry_safe (rstc , pos , & rcdev -> reset_control_head , list ) {
168+ rcu_assign_pointer (rstc -> rcdev , NULL );
169+ synchronize_srcu (& rstc -> srcu );
170+ reset_controller_remove (rcdev , rstc );
171+ }
149172}
150173EXPORT_SYMBOL_GPL (reset_controller_unregister );
151174
@@ -322,6 +345,7 @@ static inline bool reset_control_is_array(struct reset_control *rstc)
322345 */
323346int reset_control_reset (struct reset_control * rstc )
324347{
348+ struct reset_controller_dev * rcdev ;
325349 int ret ;
326350
327351 if (!rstc )
@@ -333,7 +357,13 @@ int reset_control_reset(struct reset_control *rstc)
333357 if (reset_control_is_array (rstc ))
334358 return reset_control_array_reset (rstc_to_array (rstc ));
335359
336- if (!rstc -> rcdev -> ops -> reset )
360+ guard (srcu )(& rstc -> srcu );
361+
362+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
363+ if (!rcdev )
364+ return - ENODEV ;
365+
366+ if (!rcdev -> ops -> reset )
337367 return - ENOTSUPP ;
338368
339369 if (rstc -> shared ) {
@@ -347,7 +377,7 @@ int reset_control_reset(struct reset_control *rstc)
347377 return - EPERM ;
348378 }
349379
350- ret = rstc -> rcdev -> ops -> reset (rstc -> rcdev , rstc -> id );
380+ ret = rcdev -> ops -> reset (rcdev , rstc -> id );
351381 if (rstc -> shared && ret )
352382 atomic_dec (& rstc -> triggered_count );
353383
@@ -437,6 +467,8 @@ EXPORT_SYMBOL_GPL(reset_control_rearm);
437467 */
438468int reset_control_assert (struct reset_control * rstc )
439469{
470+ struct reset_controller_dev * rcdev ;
471+
440472 if (!rstc )
441473 return 0 ;
442474
@@ -446,6 +478,12 @@ int reset_control_assert(struct reset_control *rstc)
446478 if (reset_control_is_array (rstc ))
447479 return reset_control_array_assert (rstc_to_array (rstc ));
448480
481+ guard (srcu )(& rstc -> srcu );
482+
483+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
484+ if (!rcdev )
485+ return - ENODEV ;
486+
449487 if (rstc -> shared ) {
450488 if (WARN_ON (atomic_read (& rstc -> triggered_count ) != 0 ))
451489 return - EINVAL ;
@@ -460,25 +498,25 @@ int reset_control_assert(struct reset_control *rstc)
460498 * Shared reset controls allow the reset line to be in any state
461499 * after this call, so doing nothing is a valid option.
462500 */
463- if (!rstc -> rcdev -> ops -> assert )
501+ if (!rcdev -> ops -> assert )
464502 return 0 ;
465503 } else {
466504 /*
467505 * If the reset controller does not implement .assert(), there
468506 * is no way to guarantee that the reset line is asserted after
469507 * this call.
470508 */
471- if (!rstc -> rcdev -> ops -> assert )
509+ if (!rcdev -> ops -> assert )
472510 return - ENOTSUPP ;
473511
474512 if (!rstc -> acquired ) {
475513 WARN (1 , "reset %s (ID: %u) is not acquired\n" ,
476- rcdev_name (rstc -> rcdev ), rstc -> id );
514+ rcdev_name (rcdev ), rstc -> id );
477515 return - EPERM ;
478516 }
479517 }
480518
481- return rstc -> rcdev -> ops -> assert (rstc -> rcdev , rstc -> id );
519+ return rcdev -> ops -> assert (rcdev , rstc -> id );
482520}
483521EXPORT_SYMBOL_GPL (reset_control_assert );
484522
@@ -525,6 +563,8 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
525563 */
526564int reset_control_deassert (struct reset_control * rstc )
527565{
566+ struct reset_controller_dev * rcdev ;
567+
528568 if (!rstc )
529569 return 0 ;
530570
@@ -534,6 +574,12 @@ int reset_control_deassert(struct reset_control *rstc)
534574 if (reset_control_is_array (rstc ))
535575 return reset_control_array_deassert (rstc_to_array (rstc ));
536576
577+ guard (srcu )(& rstc -> srcu );
578+
579+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
580+ if (!rcdev )
581+ return - ENODEV ;
582+
537583 if (rstc -> shared ) {
538584 if (WARN_ON (atomic_read (& rstc -> triggered_count ) != 0 ))
539585 return - EINVAL ;
@@ -543,7 +589,7 @@ int reset_control_deassert(struct reset_control *rstc)
543589 } else {
544590 if (!rstc -> acquired ) {
545591 WARN (1 , "reset %s (ID: %u) is not acquired\n" ,
546- rcdev_name (rstc -> rcdev ), rstc -> id );
592+ rcdev_name (rcdev ), rstc -> id );
547593 return - EPERM ;
548594 }
549595 }
@@ -555,10 +601,10 @@ int reset_control_deassert(struct reset_control *rstc)
555601 * case, the reset controller driver should implement .deassert() and
556602 * return -ENOTSUPP.
557603 */
558- if (!rstc -> rcdev -> ops -> deassert )
604+ if (!rcdev -> ops -> deassert )
559605 return 0 ;
560606
561- return rstc -> rcdev -> ops -> deassert (rstc -> rcdev , rstc -> id );
607+ return rcdev -> ops -> deassert (rcdev , rstc -> id );
562608}
563609EXPORT_SYMBOL_GPL (reset_control_deassert );
564610
@@ -600,14 +646,22 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_deassert);
600646 */
601647int reset_control_status (struct reset_control * rstc )
602648{
649+ struct reset_controller_dev * rcdev ;
650+
603651 if (!rstc )
604652 return 0 ;
605653
606654 if (WARN_ON (IS_ERR (rstc )) || reset_control_is_array (rstc ))
607655 return - EINVAL ;
608656
609- if (rstc -> rcdev -> ops -> status )
610- return rstc -> rcdev -> ops -> status (rstc -> rcdev , rstc -> id );
657+ guard (srcu )(& rstc -> srcu );
658+
659+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
660+ if (!rcdev )
661+ return - ENODEV ;
662+
663+ if (rcdev -> ops -> status )
664+ return rcdev -> ops -> status (rcdev , rstc -> id );
611665
612666 return - ENOTSUPP ;
613667}
@@ -635,6 +689,7 @@ EXPORT_SYMBOL_GPL(reset_control_status);
635689 */
636690int reset_control_acquire (struct reset_control * rstc )
637691{
692+ struct reset_controller_dev * rcdev ;
638693 struct reset_control * rc ;
639694
640695 if (!rstc )
@@ -651,7 +706,13 @@ int reset_control_acquire(struct reset_control *rstc)
651706 if (rstc -> acquired )
652707 return 0 ;
653708
654- list_for_each_entry (rc , & rstc -> rcdev -> reset_control_head , list ) {
709+ guard (srcu )(& rstc -> srcu );
710+
711+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
712+ if (!rcdev )
713+ return - ENODEV ;
714+
715+ list_for_each_entry (rc , & rcdev -> reset_control_head , list ) {
655716 if (rstc != rc && rstc -> id == rc -> id ) {
656717 if (rc -> acquired )
657718 return - EBUSY ;
@@ -743,6 +804,7 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
743804 bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED ;
744805 bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED ;
745806 struct reset_control * rstc ;
807+ int ret ;
746808
747809 lockdep_assert_held (& reset_list_mutex );
748810
@@ -773,12 +835,19 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
773835 if (!rstc )
774836 return ERR_PTR (- ENOMEM );
775837
838+ ret = init_srcu_struct (& rstc -> srcu );
839+ if (ret ) {
840+ kfree (rstc );
841+ return ERR_PTR (ret );
842+ }
843+
776844 if (!try_module_get (rcdev -> owner )) {
845+ cleanup_srcu_struct (& rstc -> srcu );
777846 kfree (rstc );
778847 return ERR_PTR (- ENODEV );
779848 }
780849
781- rstc -> rcdev = rcdev ;
850+ rcu_assign_pointer ( rstc -> rcdev , rcdev ) ;
782851 list_add (& rstc -> list , & rcdev -> reset_control_head );
783852 rstc -> id = index ;
784853 kref_init (& rstc -> refcnt );
@@ -793,13 +862,18 @@ static void __reset_control_release(struct kref *kref)
793862{
794863 struct reset_control * rstc = container_of (kref , struct reset_control ,
795864 refcnt );
865+ struct reset_controller_dev * rcdev ;
796866
797867 lockdep_assert_held (& reset_list_mutex );
798868
799- module_put (rstc -> rcdev -> owner );
869+ scoped_guard (srcu , & rstc -> srcu ) {
870+ rcdev = rcu_replace_pointer (rstc -> rcdev , NULL , true);
871+ if (rcdev )
872+ reset_controller_remove (rcdev , rstc );
873+ }
800874
801- list_del (& rstc -> list );
802- put_device ( rstc -> rcdev -> dev );
875+ synchronize_srcu (& rstc -> srcu );
876+ cleanup_srcu_struct ( & rstc -> srcu );
803877 kfree (rstc );
804878}
805879
0 commit comments