@@ -49,6 +49,7 @@ static DEFINE_IDA(reset_gpio_ida);
4949 * @triggered_count: Number of times this reset line has been reset. Currently
5050 * only used for shared resets, which means that the value
5151 * will be either 0 or 1.
52+ * @lock: serializes the internals of reset_control_acquire()
5253 */
5354struct reset_control {
5455 struct reset_controller_dev __rcu * rcdev ;
@@ -61,6 +62,7 @@ struct reset_control {
6162 bool array ;
6263 atomic_t deassert_count ;
6364 atomic_t triggered_count ;
65+ struct mutex lock ;
6466};
6567
6668/**
@@ -707,7 +709,7 @@ int reset_control_acquire(struct reset_control *rstc)
707709 if (reset_control_is_array (rstc ))
708710 return reset_control_array_acquire (rstc_to_array (rstc ));
709711
710- guard (mutex )(& reset_list_mutex );
712+ guard (mutex )(& rstc -> lock );
711713
712714 if (rstc -> acquired )
713715 return 0 ;
@@ -859,6 +861,7 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
859861 list_add (& rstc -> list , & rcdev -> reset_control_head );
860862 rstc -> id = index ;
861863 kref_init (& rstc -> refcnt );
864+ mutex_init (& rstc -> lock );
862865 rstc -> acquired = acquired ;
863866 rstc -> shared = shared ;
864867 get_device (rcdev -> dev );
@@ -872,29 +875,40 @@ static void __reset_control_release(struct kref *kref)
872875 refcnt );
873876 struct reset_controller_dev * rcdev ;
874877
875- lockdep_assert_held (& reset_list_mutex );
878+ lockdep_assert_held (& rstc -> srcu );
876879
877- scoped_guard (srcu , & rstc -> srcu ) {
878- rcdev = rcu_replace_pointer (rstc -> rcdev , NULL , true);
879- if (rcdev ) {
880- guard (mutex )(& rcdev -> lock );
881- reset_controller_remove (rcdev , rstc );
882- }
880+ rcdev = rcu_replace_pointer (rstc -> rcdev , NULL , true);
881+ if (rcdev ) {
882+ lockdep_assert_held (& rcdev -> lock );
883+ reset_controller_remove (rcdev , rstc );
883884 }
884885
885- synchronize_srcu (& rstc -> srcu );
886- cleanup_srcu_struct (& rstc -> srcu );
887- kfree (rstc );
886+ mutex_destroy (& rstc -> lock );
888887}
889888
890- static void __reset_control_put_internal (struct reset_control * rstc )
889+ static void reset_control_put_internal (struct reset_control * rstc )
891890{
892- lockdep_assert_held (& reset_list_mutex );
891+ struct reset_controller_dev * rcdev ;
892+ int ret = 0 ;
893893
894894 if (IS_ERR_OR_NULL (rstc ))
895895 return ;
896896
897- kref_put (& rstc -> refcnt , __reset_control_release );
897+ scoped_guard (srcu , & rstc -> srcu ) {
898+ rcdev = srcu_dereference (rstc -> rcdev , & rstc -> srcu );
899+ if (!rcdev )
900+ /* Already released. */
901+ return ;
902+
903+ guard (mutex )(& rcdev -> lock );
904+ ret = kref_put (& rstc -> refcnt , __reset_control_release );
905+ }
906+
907+ if (ret ) {
908+ synchronize_srcu (& rstc -> srcu );
909+ cleanup_srcu_struct (& rstc -> srcu );
910+ kfree (rstc );
911+ }
898912}
899913
900914static void reset_gpio_aux_device_release (struct device * dev )
@@ -1104,7 +1118,7 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
11041118{
11051119 bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL ;
11061120 bool gpio_fallback = false;
1107- struct reset_control * rstc ;
1121+ struct reset_control * rstc = ERR_PTR ( - EINVAL ) ;
11081122 struct reset_controller_dev * rcdev ;
11091123 struct of_phandle_args args ;
11101124 int rstc_id ;
@@ -1169,8 +1183,8 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
11691183
11701184 flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL ;
11711185
1172- /* reset_list_mutex also protects the rcdev's reset_control list */
1173- rstc = __reset_control_get_internal (rcdev , rstc_id , flags );
1186+ scoped_guard ( mutex , & rcdev -> lock )
1187+ rstc = __reset_control_get_internal (rcdev , rstc_id , flags );
11741188
11751189out_put :
11761190 of_node_put (args .np );
@@ -1213,10 +1227,8 @@ int __reset_control_bulk_get(struct device *dev, int num_rstcs,
12131227 return 0 ;
12141228
12151229err :
1216- guard (mutex )(& reset_list_mutex );
1217-
12181230 while (i -- )
1219- __reset_control_put_internal (rstcs [i ].rstc );
1231+ reset_control_put_internal (rstcs [i ].rstc );
12201232
12211233 return ret ;
12221234}
@@ -1226,10 +1238,8 @@ static void reset_control_array_put(struct reset_control_array *resets)
12261238{
12271239 int i ;
12281240
1229- guard (mutex )(& reset_list_mutex );
1230-
12311241 for (i = 0 ; i < resets -> num_rstcs ; i ++ )
1232- __reset_control_put_internal (resets -> rstc [i ]);
1242+ reset_control_put_internal (resets -> rstc [i ]);
12331243 kfree (resets );
12341244}
12351245
@@ -1247,9 +1257,7 @@ void reset_control_put(struct reset_control *rstc)
12471257 return ;
12481258 }
12491259
1250- guard (mutex )(& reset_list_mutex );
1251-
1252- __reset_control_put_internal (rstc );
1260+ reset_control_put_internal (rstc );
12531261}
12541262EXPORT_SYMBOL_GPL (reset_control_put );
12551263
@@ -1260,10 +1268,8 @@ EXPORT_SYMBOL_GPL(reset_control_put);
12601268 */
12611269void reset_control_bulk_put (int num_rstcs , struct reset_control_bulk_data * rstcs )
12621270{
1263- guard (mutex )(& reset_list_mutex );
1264-
12651271 while (num_rstcs -- )
1266- __reset_control_put_internal (rstcs [num_rstcs ].rstc );
1272+ reset_control_put_internal (rstcs [num_rstcs ].rstc );
12671273}
12681274EXPORT_SYMBOL_GPL (reset_control_bulk_put );
12691275
@@ -1482,10 +1488,8 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag
14821488 return & resets -> base ;
14831489
14841490err_rst :
1485- guard (mutex )(& reset_list_mutex );
1486-
14871491 while (-- i >= 0 )
1488- __reset_control_put_internal (resets -> rstc [i ]);
1492+ reset_control_put_internal (resets -> rstc [i ]);
14891493
14901494 kfree (resets );
14911495
0 commit comments