kernel: bump 5.10 to 5.10.24
[openwrt/staging/hauke.git] / target / linux / bcm63xx / patches-5.10 / 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 @@ -644,23 +644,30 @@ static struct gpio_desc *of_parse_own_gp
33 * of_gpiochip_add_hog - Add all hogs in a hog device node
34 * @chip: gpio chip to act on
35 * @hog: device node describing the hogs
36 + * @start: first gpio to check
37 + * @num: number of gpios to check
38 *
39 * Returns error if it fails otherwise 0 on success.
40 */
41 -static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog)
42 +static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog,
43 + unsigned int start, unsigned int num)
44 {
45 enum gpiod_flags dflags;
46 struct gpio_desc *desc;
47 unsigned long lflags;
48 const char *name;
49 unsigned int i;
50 - int ret;
51 + int ret, hwgpio;
52
53 for (i = 0;; i++) {
54 desc = of_parse_own_gpio(hog, chip, i, &name, &lflags, &dflags);
55 if (IS_ERR(desc))
56 break;
57
58 + hwgpio = gpio_chip_hwgpio(desc);
59 + if (hwgpio < start || hwgpio >= (start + num))
60 + continue;
61 +
62 ret = gpiod_hog(desc, name, lflags, dflags);
63 if (ret < 0)
64 return ret;
65 @@ -676,12 +683,15 @@ static int of_gpiochip_add_hog(struct gp
66 /**
67 * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
68 * @chip: gpio chip to act on
69 + * @start: first gpio to check
70 + * @num: number of gpios to check
71 *
72 - * This is only used by of_gpiochip_add to request/set GPIO initial
73 - * configuration.
74 + * This is used by of_gpiochip_add, gpiochip_add_pingroup_range and
75 + * gpiochip_add_pin_range to request/set GPIO initial configuration.
76 * It returns error if it fails otherwise 0 on success.
77 */
78 -static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
79 +int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
80 + unsigned int num)
81 {
82 struct device_node *np;
83 int ret;
84 @@ -690,7 +700,7 @@ static int of_gpiochip_scan_gpios(struct
85 if (!of_property_read_bool(np, "gpio-hog"))
86 continue;
87
88 - ret = of_gpiochip_add_hog(chip, np);
89 + ret = of_gpiochip_add_hog(chip, np, start, num);
90 if (ret < 0) {
91 of_node_put(np);
92 return ret;
93 @@ -756,7 +766,7 @@ static int of_gpio_notify(struct notifie
94 if (chip == NULL)
95 return NOTIFY_OK; /* not for us */
96
97 - ret = of_gpiochip_add_hog(chip, rd->dn);
98 + ret = of_gpiochip_add_hog(chip, rd->dn, 0, chip->ngpio);
99 if (ret < 0) {
100 pr_err("%s: failed to add hogs for %pOF\n", __func__,
101 rd->dn);
102 @@ -1028,9 +1038,11 @@ int of_gpiochip_add(struct gpio_chip *ch
103
104 of_node_get(chip->of_node);
105
106 - ret = of_gpiochip_scan_gpios(chip);
107 - if (ret)
108 - of_node_put(chip->of_node);
109 + if (!chip->request) {
110 + ret = of_gpiochip_scan_gpios(chip, 0, chip->ngpio);
111 + if (ret)
112 + of_node_put(chip->of_node);
113 + }
114
115 return ret;
116 }
117 --- a/drivers/gpio/gpiolib.c
118 +++ b/drivers/gpio/gpiolib.c
119 @@ -1890,7 +1890,8 @@ int gpiochip_add_pingroup_range(struct g
120
121 list_add_tail(&pin_range->node, &gdev->pin_ranges);
122
123 - return 0;
124 + return of_gpiochip_scan_gpios(gc, gpio_offset,
125 + pin_range->range.npins);
126 }
127 EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range);
128
129 @@ -1947,7 +1948,7 @@ int gpiochip_add_pin_range(struct gpio_c
130
131 list_add_tail(&pin_range->node, &gdev->pin_ranges);
132
133 - return 0;
134 + return of_gpiochip_scan_gpios(gc, gpio_offset, npins);
135 }
136 EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
137
138 --- a/drivers/gpio/gpiolib-of.h
139 +++ b/drivers/gpio/gpiolib-of.h
140 @@ -13,6 +13,8 @@ struct gpio_desc *of_find_gpio(struct de
141 unsigned long *lookupflags);
142 int of_gpiochip_add(struct gpio_chip *gc);
143 void of_gpiochip_remove(struct gpio_chip *gc);
144 +int of_gpiochip_scan_gpios(struct gpio_chip *chip, unsigned int start,
145 + unsigned int num);
146 int of_gpio_get_count(struct device *dev, const char *con_id);
147 bool of_gpio_need_valid_mask(const struct gpio_chip *gc);
148 #else
149 @@ -25,6 +27,12 @@ static inline struct gpio_desc *of_find_
150 }
151 static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
152 static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
153 +static inline int of_gpiochip_scan_gpios(struct gpio_chip *chip,
154 + unsigned int start,
155 + unsigned int num)
156 +{
157 + return 0;
158 +}
159 static inline int of_gpio_get_count(struct device *dev, const char *con_id)
160 {
161 return 0;