From e38d457de7be63e6ced1ea254aa51466deb1fef0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 10 Nov 2012 21:53:20 +0800 Subject: 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 Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'drivers/pinctrl/pinmux.c') 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) dev_err(pctldev->dev, "could not request pin %d on device %s\n", pins[i], pinctrl_dev_get_name(pctldev)); - /* On error release all taken pins */ - i--; /* this pin just failed */ - for (; i >= 0; i--) - pin_free(pctldev, pins[i], NULL); - return -ENODEV; + goto err_pin_request; } } @@ -429,8 +425,26 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) desc->mux_setting = &(setting->data.mux); } - return ops->enable(pctldev, setting->data.mux.func, - setting->data.mux.group); + ret = ops->enable(pctldev, setting->data.mux.func, + setting->data.mux.group); + + if (ret) + goto err_enable; + + return 0; + +err_enable: + for (i = 0; i < num_pins; i++) { + desc = pin_desc_get(pctldev, pins[i]); + if (desc) + desc->mux_setting = NULL; + } +err_pin_request: + /* On error release all taken pins */ + while (--i >= 0) + pin_free(pctldev, pins[i], NULL); + + return ret; } void pinmux_disable_setting(struct pinctrl_setting const *setting) -- cgit v1.2.3