diff options
author | Stephen Warren <swarren@nvidia.com> | 2011-10-21 14:25:53 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-01-03 03:09:59 -0500 |
commit | 3712a3c488987849613a4ad74129e67e40b12b38 (patch) | |
tree | c3b155ed171bb0542d6ea4b18dcfc3d279ee610f /drivers/pinctrl/pinmux.c | |
parent | d2f6a1c6fb0e510a24ccac066eefbcfd0c932858 (diff) |
pinctrl: add explicit gpio_disable_free pinmux_op
Some pinctrl drivers (Tegra at least) program a pin to be a GPIO in a
completely different manner than they select which function to mux out of
that pin. In order to support a single "free" pinmux_op, the driver would
need to maintain a per-pin state of requested-for-gpio vs. requested-for-
function. However, that's a lot of work when the core already has explicit
separate paths for gpio request/free and function request/free.
So, add a gpio_disable_free op to struct pinmux_ops, and make pin_free()
call it when appropriate.
When doing this, I noticed that when calling pin_request():
!!gpio == (gpio_range != NULL)
... and so I collapsed those two parameters in both pin_request(), and
when adding writing the new code in pin_free().
Also, for pin_free():
!!free_func == (gpio_range != NULL)
However, I didn't want pin_free() to know about the GPIO function naming
special case, so instead, I reworked pin_free() to always return the pin's
previously requested function, and now pinmux_free_gpio() calls
kfree(function). This is much more balanced with the allocation having
been performed in pinmux_request_gpio().
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinmux.c')
-rw-r--r-- | drivers/pinctrl/pinmux.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 17c3931d5ef0..c77aee5508fb 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -94,12 +94,11 @@ struct pinmux_hog { | |||
94 | * @function: a functional name to give to this pin, passed to the driver | 94 | * @function: a functional name to give to this pin, passed to the driver |
95 | * so it knows what function to mux in, e.g. the string "gpioNN" | 95 | * so it knows what function to mux in, e.g. the string "gpioNN" |
96 | * means that you want to mux in the pin for use as GPIO number NN | 96 | * means that you want to mux in the pin for use as GPIO number NN |
97 | * @gpio: if this request concerns a single GPIO pin | ||
98 | * @gpio_range: the range matching the GPIO pin if this is a request for a | 97 | * @gpio_range: the range matching the GPIO pin if this is a request for a |
99 | * single GPIO pin | 98 | * single GPIO pin |
100 | */ | 99 | */ |
101 | static int pin_request(struct pinctrl_dev *pctldev, | 100 | static int pin_request(struct pinctrl_dev *pctldev, |
102 | int pin, const char *function, bool gpio, | 101 | int pin, const char *function, |
103 | struct pinctrl_gpio_range *gpio_range) | 102 | struct pinctrl_gpio_range *gpio_range) |
104 | { | 103 | { |
105 | struct pin_desc *desc; | 104 | struct pin_desc *desc; |
@@ -143,7 +142,7 @@ static int pin_request(struct pinctrl_dev *pctldev, | |||
143 | * If there is no kind of request function for the pin we just assume | 142 | * If there is no kind of request function for the pin we just assume |
144 | * we got it by default and proceed. | 143 | * we got it by default and proceed. |
145 | */ | 144 | */ |
146 | if (gpio && ops->gpio_request_enable) | 145 | if (gpio_range && ops->gpio_request_enable) |
147 | /* This requests and enables a single GPIO pin */ | 146 | /* This requests and enables a single GPIO pin */ |
148 | status = ops->gpio_request_enable(pctldev, gpio_range, pin); | 147 | status = ops->gpio_request_enable(pctldev, gpio_range, pin); |
149 | else if (ops->request) | 148 | else if (ops->request) |
@@ -173,29 +172,39 @@ out: | |||
173 | * pin_free() - release a single muxed in pin so something else can be muxed | 172 | * pin_free() - release a single muxed in pin so something else can be muxed |
174 | * @pctldev: pin controller device handling this pin | 173 | * @pctldev: pin controller device handling this pin |
175 | * @pin: the pin to free | 174 | * @pin: the pin to free |
176 | * @free_func: whether to free the pin's assigned function name string | 175 | * @gpio_range: the range matching the GPIO pin if this is a request for a |
176 | * single GPIO pin | ||
177 | */ | 177 | */ |
178 | static void pin_free(struct pinctrl_dev *pctldev, int pin, int free_func) | 178 | static const char *pin_free(struct pinctrl_dev *pctldev, int pin, |
179 | struct pinctrl_gpio_range *gpio_range) | ||
179 | { | 180 | { |
180 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 181 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
181 | struct pin_desc *desc; | 182 | struct pin_desc *desc; |
183 | const char *func; | ||
182 | 184 | ||
183 | desc = pin_desc_get(pctldev, pin); | 185 | desc = pin_desc_get(pctldev, pin); |
184 | if (desc == NULL) { | 186 | if (desc == NULL) { |
185 | dev_err(&pctldev->dev, | 187 | dev_err(&pctldev->dev, |
186 | "pin is not registered so it cannot be freed\n"); | 188 | "pin is not registered so it cannot be freed\n"); |
187 | return; | 189 | return NULL; |
188 | } | 190 | } |
189 | 191 | ||
190 | if (ops->free) | 192 | /* |
193 | * If there is no kind of request function for the pin we just assume | ||
194 | * we got it by default and proceed. | ||
195 | */ | ||
196 | if (gpio_range && ops->gpio_disable_free) | ||
197 | ops->gpio_disable_free(pctldev, gpio_range, pin); | ||
198 | else if (ops->free) | ||
191 | ops->free(pctldev, pin); | 199 | ops->free(pctldev, pin); |
192 | 200 | ||
193 | spin_lock(&desc->lock); | 201 | spin_lock(&desc->lock); |
194 | if (free_func) | 202 | func = desc->mux_function; |
195 | kfree(desc->mux_function); | ||
196 | desc->mux_function = NULL; | 203 | desc->mux_function = NULL; |
197 | spin_unlock(&desc->lock); | 204 | spin_unlock(&desc->lock); |
198 | module_put(pctldev->owner); | 205 | module_put(pctldev->owner); |
206 | |||
207 | return func; | ||
199 | } | 208 | } |
200 | 209 | ||
201 | /** | 210 | /** |
@@ -225,7 +234,7 @@ int pinmux_request_gpio(unsigned gpio) | |||
225 | if (!function) | 234 | if (!function) |
226 | return -EINVAL; | 235 | return -EINVAL; |
227 | 236 | ||
228 | ret = pin_request(pctldev, pin, function, true, range); | 237 | ret = pin_request(pctldev, pin, function, range); |
229 | if (ret < 0) | 238 | if (ret < 0) |
230 | kfree(function); | 239 | kfree(function); |
231 | 240 | ||
@@ -243,6 +252,7 @@ void pinmux_free_gpio(unsigned gpio) | |||
243 | struct pinctrl_gpio_range *range; | 252 | struct pinctrl_gpio_range *range; |
244 | int ret; | 253 | int ret; |
245 | int pin; | 254 | int pin; |
255 | const char *func; | ||
246 | 256 | ||
247 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); | 257 | ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); |
248 | if (ret) | 258 | if (ret) |
@@ -251,7 +261,8 @@ void pinmux_free_gpio(unsigned gpio) | |||
251 | /* Convert to the pin controllers number space */ | 261 | /* Convert to the pin controllers number space */ |
252 | pin = gpio - range->base; | 262 | pin = gpio - range->base; |
253 | 263 | ||
254 | pin_free(pctldev, pin, true); | 264 | func = pin_free(pctldev, pin, range); |
265 | kfree(func); | ||
255 | } | 266 | } |
256 | EXPORT_SYMBOL_GPL(pinmux_free_gpio); | 267 | EXPORT_SYMBOL_GPL(pinmux_free_gpio); |
257 | 268 | ||
@@ -341,7 +352,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, | |||
341 | 352 | ||
342 | /* Try to allocate all pins in this group, one by one */ | 353 | /* Try to allocate all pins in this group, one by one */ |
343 | for (i = 0; i < num_pins; i++) { | 354 | for (i = 0; i < num_pins; i++) { |
344 | ret = pin_request(pctldev, pins[i], func, false, NULL); | 355 | ret = pin_request(pctldev, pins[i], func, NULL); |
345 | if (ret) { | 356 | if (ret) { |
346 | dev_err(&pctldev->dev, | 357 | dev_err(&pctldev->dev, |
347 | "could not get pin %d for function %s " | 358 | "could not get pin %d for function %s " |
@@ -351,7 +362,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, | |||
351 | /* On error release all taken pins */ | 362 | /* On error release all taken pins */ |
352 | i--; /* this pin just failed */ | 363 | i--; /* this pin just failed */ |
353 | for (; i >= 0; i--) | 364 | for (; i >= 0; i--) |
354 | pin_free(pctldev, pins[i], false); | 365 | pin_free(pctldev, pins[i], NULL); |
355 | return -ENODEV; | 366 | return -ENODEV; |
356 | } | 367 | } |
357 | } | 368 | } |
@@ -381,7 +392,7 @@ static void release_pins(struct pinctrl_dev *pctldev, | |||
381 | return; | 392 | return; |
382 | } | 393 | } |
383 | for (i = 0; i < num_pins; i++) | 394 | for (i = 0; i < num_pins; i++) |
384 | pin_free(pctldev, pins[i], false); | 395 | pin_free(pctldev, pins[i], NULL); |
385 | } | 396 | } |
386 | 397 | ||
387 | /** | 398 | /** |