@@ -36,6 +36,8 @@ struct gpio_shared_ref {
3636 enum gpiod_flags flags ;
3737 char * con_id ;
3838 int dev_id ;
39+ /* Protects the auxiliary device struct and the lookup table. */
40+ struct mutex lock ;
3941 struct auxiliary_device adev ;
4042 struct gpiod_lookup_table * lookup ;
4143};
@@ -49,14 +51,14 @@ struct gpio_shared_entry {
4951 unsigned int offset ;
5052 /* Index in the property value array. */
5153 size_t index ;
54+ /* Synchronizes the modification of shared_desc. */
5255 struct mutex lock ;
5356 struct gpio_shared_desc * shared_desc ;
5457 struct kref ref ;
5558 struct list_head refs ;
5659};
5760
5861static LIST_HEAD (gpio_shared_list );
59- static DEFINE_MUTEX (gpio_shared_lock );
6062static DEFINE_IDA (gpio_shared_ida );
6163
6264#if IS_ENABLED (CONFIG_OF )
@@ -77,6 +79,10 @@ gpio_shared_find_entry(struct fwnode_handle *controller_node,
7779/* Handle all special nodes that we should ignore. */
7880static bool gpio_shared_of_node_ignore (struct device_node * node )
7981{
82+ /* Ignore disabled devices. */
83+ if (!of_device_is_available (node ))
84+ return true;
85+
8086 /*
8187 * __symbols__ is a special, internal node and should not be considered
8288 * when scanning for shared GPIOs.
@@ -183,6 +189,7 @@ static int gpio_shared_of_traverse(struct device_node *curr)
183189
184190 ref -> fwnode = fwnode_handle_get (of_fwnode_handle (curr ));
185191 ref -> flags = args .args [1 ];
192+ mutex_init (& ref -> lock );
186193
187194 if (strends (prop -> name , "gpios" ))
188195 suffix = "-gpios" ;
@@ -254,7 +261,7 @@ static int gpio_shared_make_adev(struct gpio_device *gdev,
254261 struct auxiliary_device * adev = & ref -> adev ;
255262 int ret ;
256263
257- lockdep_assert_held ( & gpio_shared_lock );
264+ guard ( mutex )( & ref -> lock );
258265
259266 memset (adev , 0 , sizeof (* adev ));
260267
@@ -369,14 +376,14 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags)
369376 if (!lookup )
370377 return - ENOMEM ;
371378
372- guard (mutex )(& gpio_shared_lock );
373-
374379 list_for_each_entry (entry , & gpio_shared_list , list ) {
375380 list_for_each_entry (ref , & entry -> refs , list ) {
376381 if (!device_match_fwnode (consumer , ref -> fwnode ) &&
377382 !gpio_shared_dev_is_reset_gpio (consumer , entry , ref ))
378383 continue ;
379384
385+ guard (mutex )(& ref -> lock );
386+
380387 /* We've already done that on a previous request. */
381388 if (ref -> lookup )
382389 return 0 ;
@@ -395,7 +402,8 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags)
395402 lookup -> table [0 ] = GPIO_LOOKUP (no_free_ptr (key ), 0 ,
396403 ref -> con_id , lflags );
397404
398- gpiod_add_lookup_table (no_free_ptr (lookup ));
405+ ref -> lookup = no_free_ptr (lookup );
406+ gpiod_add_lookup_table (ref -> lookup );
399407
400408 return 0 ;
401409 }
@@ -408,10 +416,8 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags)
408416
409417static void gpio_shared_remove_adev (struct auxiliary_device * adev )
410418{
411- lockdep_assert_held (& gpio_shared_lock );
412-
413- auxiliary_device_uninit (adev );
414419 auxiliary_device_delete (adev );
420+ auxiliary_device_uninit (adev );
415421}
416422
417423int gpio_device_setup_shared (struct gpio_device * gdev )
@@ -421,8 +427,6 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
421427 unsigned long * flags ;
422428 int ret ;
423429
424- guard (mutex )(& gpio_shared_lock );
425-
426430 list_for_each_entry (entry , & gpio_shared_list , list ) {
427431 list_for_each_entry (ref , & entry -> refs , list ) {
428432 if (gdev -> dev .parent == & ref -> adev .dev ) {
@@ -479,19 +483,32 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
479483 struct gpio_shared_entry * entry ;
480484 struct gpio_shared_ref * ref ;
481485
482- guard (mutex )(& gpio_shared_lock );
483-
484486 list_for_each_entry (entry , & gpio_shared_list , list ) {
485487 if (!device_match_fwnode (& gdev -> dev , entry -> fwnode ))
486488 continue ;
487489
490+ /*
491+ * For some reason if we call synchronize_srcu() in GPIO core,
492+ * descent here and take this mutex and then recursively call
493+ * synchronize_srcu() again from gpiochip_remove() (which is
494+ * totally fine) called after gpio_shared_remove_adev(),
495+ * lockdep prints a false positive deadlock splat. Disable
496+ * lockdep here.
497+ */
498+ lockdep_off ();
488499 list_for_each_entry (ref , & entry -> refs , list ) {
489- gpiod_remove_lookup_table (ref -> lookup );
490- kfree (ref -> lookup -> table [0 ].key );
491- kfree (ref -> lookup );
492- ref -> lookup = NULL ;
500+ guard (mutex )(& ref -> lock );
501+
502+ if (ref -> lookup ) {
503+ gpiod_remove_lookup_table (ref -> lookup );
504+ kfree (ref -> lookup -> table [0 ].key );
505+ kfree (ref -> lookup );
506+ ref -> lookup = NULL ;
507+ }
508+
493509 gpio_shared_remove_adev (& ref -> adev );
494510 }
511+ lockdep_on ();
495512 }
496513}
497514
@@ -515,8 +532,6 @@ static void gpiod_shared_put(void *data)
515532{
516533 struct gpio_shared_entry * entry = data ;
517534
518- lockdep_assert_not_held (& gpio_shared_lock );
519-
520535 kref_put (& entry -> ref , gpio_shared_release );
521536}
522537
@@ -554,8 +569,6 @@ struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev)
554569 struct gpio_shared_entry * entry ;
555570 int ret ;
556571
557- lockdep_assert_not_held (& gpio_shared_lock );
558-
559572 entry = dev_get_platdata (dev );
560573 if (WARN_ON (!entry ))
561574 /* Programmer bug */
@@ -590,6 +603,7 @@ EXPORT_SYMBOL_GPL(devm_gpiod_shared_get);
590603static void gpio_shared_drop_ref (struct gpio_shared_ref * ref )
591604{
592605 list_del (& ref -> list );
606+ mutex_destroy (& ref -> lock );
593607 kfree (ref -> con_id );
594608 ida_free (& gpio_shared_ida , ref -> dev_id );
595609 fwnode_handle_put (ref -> fwnode );
0 commit comments