diff options
author | Axel Lin <axel.lin@ingics.com> | 2012-11-10 08:53:20 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-11-11 14:18:32 -0500 |
commit | e38d457de7be63e6ced1ea254aa51466deb1fef0 (patch) | |
tree | 6e18c36639a0de0e0f5ad44c50b67a2adf1e20a7 /drivers/pinctrl | |
parent | 89377aa5156a93e73a3f7c7ccdc0d0fecf65e0d2 (diff) |
pinctrl: pinmux: Release all taken pins in pinmux_enable_setting error paths
Currently pinmux_enable_setting does not release all taken pins if
ops->enable() returns error. This patch ensures all taken pins are
released in any error paths.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/pinmux.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 0ef01ee2835f..1a00658b3ea0 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -409,11 +409,7 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
409 | dev_err(pctldev->dev, | 409 | dev_err(pctldev->dev, |
410 | "could not request pin %d on device %s\n", | 410 | "could not request pin %d on device %s\n", |
411 | pins[i], pinctrl_dev_get_name(pctldev)); | 411 | pins[i], pinctrl_dev_get_name(pctldev)); |
412 | /* On error release all taken pins */ | 412 | goto err_pin_request; |
413 | i--; /* this pin just failed */ | ||
414 | for (; i >= 0; i--) | ||
415 | pin_free(pctldev, pins[i], NULL); | ||
416 | return -ENODEV; | ||
417 | } | 413 | } |
418 | } | 414 | } |
419 | 415 | ||
@@ -429,8 +425,26 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
429 | desc->mux_setting = &(setting->data.mux); | 425 | desc->mux_setting = &(setting->data.mux); |
430 | } | 426 | } |
431 | 427 | ||
432 | return ops->enable(pctldev, setting->data.mux.func, | 428 | ret = ops->enable(pctldev, setting->data.mux.func, |
433 | setting->data.mux.group); | 429 | setting->data.mux.group); |
430 | |||
431 | if (ret) | ||
432 | goto err_enable; | ||
433 | |||
434 | return 0; | ||
435 | |||
436 | err_enable: | ||
437 | for (i = 0; i < num_pins; i++) { | ||
438 | desc = pin_desc_get(pctldev, pins[i]); | ||
439 | if (desc) | ||
440 | desc->mux_setting = NULL; | ||
441 | } | ||
442 | err_pin_request: | ||
443 | /* On error release all taken pins */ | ||
444 | while (--i >= 0) | ||
445 | pin_free(pctldev, pins[i], NULL); | ||
446 | |||
447 | return ret; | ||
434 | } | 448 | } |
435 | 449 | ||
436 | void pinmux_disable_setting(struct pinctrl_setting const *setting) | 450 | void pinmux_disable_setting(struct pinctrl_setting const *setting) |