Commit 5d2eaf8090874f8e65388e82f7e91f9cef74885e
Committed by
Linus Walleij
1 parent
9af1e44fb4
Exists in
master
and in
6 other branches
pinctrl: Don't copy function name when requesting a pin
Instead, store a pointer to the currently assigned function. This allows us to delete the mux_requested variable from pin_desc; a pin is requested if its currently assigned function is non-NULL. When a pin is requested as a GPIO rather than a regular function, the assigned function name is dynamically constructed. In this case, we have to kstrdup() the dynamically constructed name, so that mux_function doesn't pointed at stack data. This requires pin_free to be told whether to free the mux_function pointer or not. This removes the hard-coded maximum function name length. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Showing 2 changed files with 24 additions and 15 deletions Side-by-side Diff
drivers/pinctrl/core.h
drivers/pinctrl/pinmux.c
... | ... | @@ -130,14 +130,13 @@ |
130 | 130 | } |
131 | 131 | |
132 | 132 | spin_lock(&desc->lock); |
133 | - if (desc->mux_requested) { | |
133 | + if (desc->mux_function) { | |
134 | 134 | spin_unlock(&desc->lock); |
135 | 135 | dev_err(&pctldev->dev, |
136 | 136 | "pin already requested\n"); |
137 | 137 | goto out; |
138 | 138 | } |
139 | - desc->mux_requested = true; | |
140 | - strncpy(desc->mux_function, function, sizeof(desc->mux_function)); | |
139 | + desc->mux_function = function; | |
141 | 140 | spin_unlock(&desc->lock); |
142 | 141 | |
143 | 142 | /* Let each pin increase references to this module */ |
... | ... | @@ -168,8 +167,7 @@ |
168 | 167 | out_free_pin: |
169 | 168 | if (status) { |
170 | 169 | spin_lock(&desc->lock); |
171 | - desc->mux_requested = false; | |
172 | - desc->mux_function[0] = '\0'; | |
170 | + desc->mux_function = NULL; | |
173 | 171 | spin_unlock(&desc->lock); |
174 | 172 | } |
175 | 173 | out: |
176 | 174 | |
... | ... | @@ -184,8 +182,9 @@ |
184 | 182 | * pin_free() - release a single muxed in pin so something else can be muxed |
185 | 183 | * @pctldev: pin controller device handling this pin |
186 | 184 | * @pin: the pin to free |
185 | + * @free_func: whether to free the pin's assigned function name string | |
187 | 186 | */ |
188 | -static void pin_free(struct pinctrl_dev *pctldev, int pin) | |
187 | +static void pin_free(struct pinctrl_dev *pctldev, int pin, int free_func) | |
189 | 188 | { |
190 | 189 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
191 | 190 | struct pin_desc *desc; |
... | ... | @@ -201,8 +200,9 @@ |
201 | 200 | ops->free(pctldev, pin); |
202 | 201 | |
203 | 202 | spin_lock(&desc->lock); |
204 | - desc->mux_requested = false; | |
205 | - desc->mux_function[0] = '\0'; | |
203 | + if (free_func) | |
204 | + kfree(desc->mux_function); | |
205 | + desc->mux_function = NULL; | |
206 | 206 | spin_unlock(&desc->lock); |
207 | 207 | module_put(pctldev->owner); |
208 | 208 | } |
... | ... | @@ -214,6 +214,7 @@ |
214 | 214 | int pinmux_request_gpio(unsigned gpio) |
215 | 215 | { |
216 | 216 | char gpiostr[16]; |
217 | + const char *function; | |
217 | 218 | struct pinctrl_dev *pctldev; |
218 | 219 | struct pinctrl_gpio_range *range; |
219 | 220 | int ret; |
... | ... | @@ -229,7 +230,15 @@ |
229 | 230 | /* Conjure some name stating what chip and pin this is taken by */ |
230 | 231 | snprintf(gpiostr, 15, "%s:%d", range->name, gpio); |
231 | 232 | |
232 | - return pin_request(pctldev, pin, gpiostr, true, range); | |
233 | + function = kstrdup(gpiostr, GFP_KERNEL); | |
234 | + if (!function) | |
235 | + return -EINVAL; | |
236 | + | |
237 | + ret = pin_request(pctldev, pin, function, true, range); | |
238 | + if (ret < 0) | |
239 | + kfree(function); | |
240 | + | |
241 | + return ret; | |
233 | 242 | } |
234 | 243 | EXPORT_SYMBOL_GPL(pinmux_request_gpio); |
235 | 244 | |
... | ... | @@ -251,7 +260,7 @@ |
251 | 260 | /* Convert to the pin controllers number space */ |
252 | 261 | pin = gpio - range->base; |
253 | 262 | |
254 | - pin_free(pctldev, pin); | |
263 | + pin_free(pctldev, pin, true); | |
255 | 264 | } |
256 | 265 | EXPORT_SYMBOL_GPL(pinmux_free_gpio); |
257 | 266 | |
... | ... | @@ -351,7 +360,7 @@ |
351 | 360 | /* On error release all taken pins */ |
352 | 361 | i--; /* this pin just failed */ |
353 | 362 | for (; i >= 0; i--) |
354 | - pin_free(pctldev, pins[i]); | |
363 | + pin_free(pctldev, pins[i], false); | |
355 | 364 | return -ENODEV; |
356 | 365 | } |
357 | 366 | } |
... | ... | @@ -381,7 +390,7 @@ |
381 | 390 | return; |
382 | 391 | } |
383 | 392 | for (i = 0; i < num_pins; i++) |
384 | - pin_free(pctldev, pins[i]); | |
393 | + pin_free(pctldev, pins[i], false); | |
385 | 394 | } |
386 | 395 | |
387 | 396 | /** |
... | ... | @@ -1013,7 +1022,8 @@ |
1013 | 1022 | |
1014 | 1023 | seq_printf(s, "pin %d (%s): %s\n", pin, |
1015 | 1024 | desc->name ? desc->name : "unnamed", |
1016 | - desc->mux_requested ? desc->mux_function : "UNCLAIMED"); | |
1025 | + desc->mux_function ? desc->mux_function | |
1026 | + : "UNCLAIMED"); | |
1017 | 1027 | } |
1018 | 1028 | |
1019 | 1029 | return 0; |