+32
-2
drivers/gpio/gpiolib-shared.c
+32
-2
drivers/gpio/gpiolib-shared.c
···
41
41
struct lock_class_key lock_key;
42
42
struct auxiliary_device adev;
43
43
struct gpiod_lookup_table *lookup;
44
44
+
bool is_reset_gpio;
44
45
};
45
46
46
47
/* Represents a single GPIO pin. */
···
113
112
struct gpio_shared_ref *ref;
114
113
115
114
list_for_each_entry(ref, &entry->refs, list) {
116
116
-
if (!ref->fwnode && ref->con_id && strcmp(ref->con_id, "reset") == 0)
115
115
+
if (ref->is_reset_gpio)
116
116
+
/* Already set-up. */
117
117
return 0;
118
118
}
119
119
120
120
ref = gpio_shared_make_ref(NULL, "reset", flags);
121
121
if (!ref)
122
122
return -ENOMEM;
123
123
+
124
124
+
ref->is_reset_gpio = true;
123
125
124
126
list_add_tail(&ref->list, &entry->refs);
125
127
···
718
714
}
719
715
}
720
716
717
717
+
static bool gpio_shared_entry_is_really_shared(struct gpio_shared_entry *entry)
718
718
+
{
719
719
+
size_t num_nodes = list_count_nodes(&entry->refs);
720
720
+
struct gpio_shared_ref *ref;
721
721
+
722
722
+
if (num_nodes <= 1)
723
723
+
return false;
724
724
+
725
725
+
if (num_nodes > 2)
726
726
+
return true;
727
727
+
728
728
+
/* Exactly two references: */
729
729
+
list_for_each_entry(ref, &entry->refs, list) {
730
730
+
/*
731
731
+
* Corner-case: the second reference comes from the potential
732
732
+
* reset-gpio instance. However, this pin is not really shared
733
733
+
* as it would have three references in this case. Avoid
734
734
+
* creating unnecessary proxies.
735
735
+
*/
736
736
+
if (ref->is_reset_gpio)
737
737
+
return false;
738
738
+
}
739
739
+
740
740
+
return true;
741
741
+
}
742
742
+
721
743
static void gpio_shared_free_exclusive(void)
722
744
{
723
745
struct gpio_shared_entry *entry, *epos;
724
746
725
747
list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
726
726
-
if (list_count_nodes(&entry->refs) > 1)
748
748
+
if (gpio_shared_entry_is_really_shared(entry))
727
749
continue;
728
750
729
751
gpio_shared_drop_ref(list_first_entry(&entry->refs,