13225beae62b017ce0e8a1918a623067a3e11859
[oweals/openwrt.git] / target / linux / brcm63xx / patches-4.19 / 143-gpio-fix-device-tree-gpio-hogs-on-dual-role-gpio-pin.patch
1 From e058fa1969019c2f6705c53c4130e364a877d4e6 Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jonas.gorski@gmail.com>
3 Date: Sun, 26 Nov 2017 12:07:31 +0100
4 Subject: [PATCH] gpio: fix device tree gpio hogs on dual role gpio/pincontrol
5  controllers
6
7 For dual role gpio and pincontrol controller, the device registration
8 path is often:
9
10   pinctrl_register(...);
11   gpiochip_add_data(...);
12   gpiochip_add_pin_range(...);
13
14 If the device tree node has any gpio-hogs, the code will try to apply them
15 in the gpiochip_add_data step, but fail as they cannot be requested, as the
16 ranges are missing. But we also cannot first add the pinranges, as the
17 appropriate data structures are only initialized in gpiochip_add_data.
18
19 To fix this, defer gpio-hogs to the time pin ranges get added instead of
20 directly at chip request time, if the gpio-chip has a request method.
21
22 Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
23 ---
24
25  drivers/gpio/gpiolib-of.c | 20 +++++++++++++++-----
26  drivers/gpio/gpiolib.c    |  5 +++--
27  drivers/gpio/gpiolib.h    |  8 ++++++++
28  3 files changed, 26 insertions(+), 7 deletions(-)
29
30 --- a/drivers/gpio/gpiolib-of.c
31 +++ b/drivers/gpio/gpiolib-of.c
32 @@ -363,12 +363,15 @@ static struct gpio_desc *of_parse_own_gp
33  /**
34   * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
35   * @chip:      gpio chip to act on
36 + * @start:     first gpio to check
37 + * @num:       number of gpios to check
38   *
39 - * This is only used by of_gpiochip_add to request/set GPIO initial
40 - * configuration.
41 + * This is used by of_gpiochip_add, gpiochip_add_pingroup_range and
42 + * gpiochip_add_pin_range to request/set GPIO initial configuration.
43   * It returns error if it fails otherwise 0 on success.
44   */
45 -static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
46 +int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
47 +                          unsigned int num)
48  {
49         struct gpio_desc *desc = NULL;
50         struct device_node *np;
51 @@ -376,7 +379,7 @@ static int of_gpiochip_scan_gpios(struct
52         enum gpio_lookup_flags lflags;
53         enum gpiod_flags dflags;
54         unsigned int i;
55 -       int ret;
56 +       int ret, hwgpio;
57  
58         for_each_available_child_of_node(chip->of_node, np) {
59                 if (!of_property_read_bool(np, "gpio-hog"))
60 @@ -388,6 +391,10 @@ static int of_gpiochip_scan_gpios(struct
61                         if (IS_ERR(desc))
62                                 break;
63  
64 +                       hwgpio = gpio_chip_hwgpio(desc);
65 +                       if (hwgpio < start || hwgpio >= (start + num))
66 +                               continue;
67 +
68                         ret = gpiod_hog(desc, name, lflags, dflags);
69                         if (ret < 0) {
70                                 of_node_put(np);
71 @@ -646,12 +653,13 @@ int of_gpiochip_add(struct gpio_chip *ch
72  
73         of_node_get(chip->of_node);
74  
75 -       status = of_gpiochip_scan_gpios(chip);
76 -       if (status) {
77 -               of_node_put(chip->of_node);
78 -               gpiochip_remove_pin_ranges(chip);
79 +       if (!chip->request) {
80 +               status = of_gpiochip_scan_gpios(chip, 0, chip->ngpio);
81 +               if (status) {
82 +                       of_node_put(chip->of_node);
83 +                       gpiochip_remove_pin_ranges(chip);
84 +               }
85         }
86 -
87         return status;
88  }
89  
90 --- a/drivers/gpio/gpiolib.c
91 +++ b/drivers/gpio/gpiolib.c
92 @@ -2205,7 +2205,8 @@ int gpiochip_add_pingroup_range(struct g
93  
94         list_add_tail(&pin_range->node, &gdev->pin_ranges);
95  
96 -       return 0;
97 +       return of_gpiochip_scan_gpios(chip, gpio_offset,
98 +                                     pin_range->range.npins);
99  }
100  EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
101  
102 @@ -2262,7 +2263,7 @@ int gpiochip_add_pin_range(struct gpio_c
103  
104         list_add_tail(&pin_range->node, &gdev->pin_ranges);
105  
106 -       return 0;
107 +       return of_gpiochip_scan_gpios(chip, gpio_offset, npins);
108  }
109  EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
110  
111 --- a/drivers/gpio/gpiolib.h
112 +++ b/drivers/gpio/gpiolib.h
113 @@ -103,6 +103,8 @@ struct gpio_desc *of_get_named_gpiod_fla
114                    const char *list_name, int index, enum of_gpio_flags *flags);
115  int of_gpiochip_add(struct gpio_chip *gc);
116  void of_gpiochip_remove(struct gpio_chip *gc);
117 +int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
118 +                          unsigned int num);
119  #else
120  static inline struct gpio_desc *of_find_gpio(struct device *dev,
121                                              const char *con_id,
122 @@ -118,6 +120,12 @@ static inline struct gpio_desc *of_get_n
123  }
124  static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
125  static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
126 +static inline int of_gpiochip_scan_gpios(struct gpio_chip *chip,
127 +                                        unsigned int start,
128 +                                        unsigned int num)
129 +{
130 +       return 0;
131 +}
132  #endif /* CONFIG_OF_GPIO */
133  
134  #ifdef CONFIG_ACPI