diff options
author | Stephen Warren <swarren@nvidia.com> | 2011-10-19 18:19:28 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2011-10-20 05:50:07 -0400 |
commit | 5d2eaf8090874f8e65388e82f7e91f9cef74885e (patch) | |
tree | 33ad36c3ddc8674c7d583ceec281cf613293cb13 /drivers/pinctrl | |
parent | 9af1e44fb4a4c62a90bff9b095eb001764d91b65 (diff) |
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>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/core.h | 3 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.c | 36 |
2 files changed, 24 insertions, 15 deletions
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index e431aa537287..472fa1341cc0 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -59,8 +59,7 @@ struct pin_desc { | |||
59 | spinlock_t lock; | 59 | spinlock_t lock; |
60 | /* These fields only added when supporting pinmux drivers */ | 60 | /* These fields only added when supporting pinmux drivers */ |
61 | #ifdef CONFIG_PINMUX | 61 | #ifdef CONFIG_PINMUX |
62 | bool mux_requested; | 62 | const char *mux_function; |
63 | char mux_function[16]; | ||
64 | #endif | 63 | #endif |
65 | }; | 64 | }; |
66 | 65 | ||
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 90fb00d9a8a2..a5467f8709e9 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -130,14 +130,13 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | spin_lock(&desc->lock); | 132 | spin_lock(&desc->lock); |
133 | if (desc->mux_requested) { | 133 | if (desc->mux_function) { |
134 | spin_unlock(&desc->lock); | 134 | spin_unlock(&desc->lock); |
135 | dev_err(&pctldev->dev, | 135 | dev_err(&pctldev->dev, |
136 | "pin already requested\n"); | 136 | "pin already requested\n"); |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
139 | desc->mux_requested = true; | 139 | desc->mux_function = function; |
140 | strncpy(desc->mux_function, function, sizeof(desc->mux_function)); | ||
141 | spin_unlock(&desc->lock); | 140 | spin_unlock(&desc->lock); |
142 | 141 | ||
143 | /* Let each pin increase references to this module */ | 142 | /* Let each pin increase references to this module */ |
@@ -168,8 +167,7 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
168 | out_free_pin: | 167 | out_free_pin: |
169 | if (status) { | 168 | if (status) { |
170 | spin_lock(&desc->lock); | 169 | spin_lock(&desc->lock); |
171 | desc->mux_requested = false; | 170 | desc->mux_function = NULL; |
172 | desc->mux_function[0] = '\0'; | ||
173 | spin_unlock(&desc->lock); | 171 | spin_unlock(&desc->lock); |
174 | } | 172 | } |
175 | out: | 173 | out: |
@@ -184,8 +182,9 @@ out: | |||
184 | * pin_free() - release a single muxed in pin so something else can be muxed | 182 | * pin_free() - release a single muxed in pin so something else can be muxed |
185 | * @pctldev: pin controller device handling this pin | 183 | * @pctldev: pin controller device handling this pin |
186 | * @pin: the pin to free | 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 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 189 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
191 | struct pin_desc *desc; | 190 | struct pin_desc *desc; |
@@ -201,8 +200,9 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin) | |||
201 | ops->free(pctldev, pin); | 200 | ops->free(pctldev, pin); |
202 | 201 | ||
203 | spin_lock(&desc->lock); | 202 | spin_lock(&desc->lock); |
204 | desc->mux_requested = false; | 203 | if (free_func) |
205 | desc->mux_function[0] = '\0'; | 204 | kfree(desc->mux_function); |
205 | desc->mux_function = NULL; | ||
206 | spin_unlock(&desc->lock); | 206 | spin_unlock(&desc->lock); |
207 | module_put(pctldev->owner); | 207 | module_put(pctldev->owner); |
208 | } | 208 | } |
@@ -214,6 +214,7 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin) | |||
214 | int pinmux_request_gpio(unsigned gpio) | 214 | int pinmux_request_gpio(unsigned gpio) |
215 | { | 215 | { |
216 | char gpiostr[16]; | 216 | char gpiostr[16]; |
217 | const char *function; | ||
217 | struct pinctrl_dev *pctldev; | 218 | struct pinctrl_dev *pctldev; |
218 | struct pinctrl_gpio_range *range; | 219 | struct pinctrl_gpio_range *range; |
219 | int ret; | 220 | int ret; |
@@ -229,7 +230,15 @@ int pinmux_request_gpio(unsigned gpio) | |||
229 | /* Conjure some name stating what chip and pin this is taken by */ | 230 | /* Conjure some name stating what chip and pin this is taken by */ |
230 | snprintf(gpiostr, 15, "%s:%d", range->name, gpio); | 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 | EXPORT_SYMBOL_GPL(pinmux_request_gpio); | 243 | EXPORT_SYMBOL_GPL(pinmux_request_gpio); |
235 | 244 | ||
@@ -251,7 +260,7 @@ void pinmux_free_gpio(unsigned gpio) | |||
251 | /* Convert to the pin controllers number space */ | 260 | /* Convert to the pin controllers number space */ |
252 | pin = gpio - range->base; | 261 | pin = gpio - range->base; |
253 | 262 | ||
254 | pin_free(pctldev, pin); | 263 | pin_free(pctldev, pin, true); |
255 | } | 264 | } |
256 | EXPORT_SYMBOL_GPL(pinmux_free_gpio); | 265 | EXPORT_SYMBOL_GPL(pinmux_free_gpio); |
257 | 266 | ||
@@ -351,7 +360,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, | |||
351 | /* On error release all taken pins */ | 360 | /* On error release all taken pins */ |
352 | i--; /* this pin just failed */ | 361 | i--; /* this pin just failed */ |
353 | for (; i >= 0; i--) | 362 | for (; i >= 0; i--) |
354 | pin_free(pctldev, pins[i]); | 363 | pin_free(pctldev, pins[i], false); |
355 | return -ENODEV; | 364 | return -ENODEV; |
356 | } | 365 | } |
357 | } | 366 | } |
@@ -381,7 +390,7 @@ static void release_pins(struct pinctrl_dev *pctldev, | |||
381 | return; | 390 | return; |
382 | } | 391 | } |
383 | for (i = 0; i < num_pins; i++) | 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 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
1013 | 1022 | ||
1014 | seq_printf(s, "pin %d (%s): %s\n", pin, | 1023 | seq_printf(s, "pin %d (%s): %s\n", pin, |
1015 | desc->name ? desc->name : "unnamed", | 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 | return 0; | 1029 | return 0; |