pinctrl: rockchip: add return value to rockchip_set_mux
authorHeiko Stübner <heiko@sntech.de>
Tue, 25 Mar 2014 23:57:00 +0000 (00:57 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Mon, 14 Apr 2014 07:39:33 +0000 (09:39 +0200)
In a following change, rockchip_set_mux gets the possibility to fail.
Therefore add a return value to it and honor error codes in functions
using rockchip_set_mux.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/pinctrl-rockchip.c

index 23e8812d3115bb82089a8e98243d39d41119c3ee..2ac194370b732770ca6be5aef1c9a87e36f17867 100644 (file)
@@ -342,7 +342,7 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
  * @pin: pin to change
  * @mux: new mux function to set
  */
-static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 {
        struct rockchip_pinctrl *info = bank->drvdata;
        void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
@@ -365,6 +365,8 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
        writel(data, reg);
 
        spin_unlock_irqrestore(&bank->slock, flags);
+
+       return 0;
 }
 
 #define RK2928_PULL_OFFSET             0x118
@@ -560,7 +562,7 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
        const unsigned int *pins = info->groups[group].pins;
        const struct rockchip_pin_config *data = info->groups[group].data;
        struct rockchip_pin_bank *bank;
-       int cnt;
+       int cnt, ret = 0;
 
        dev_dbg(info->dev, "enable function %s group %s\n",
                info->functions[selector].name, info->groups[group].name);
@@ -571,8 +573,18 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
         */
        for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
                bank = pin_to_bank(info, pins[cnt]);
-               rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
-                                data[cnt].func);
+               ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+                                      data[cnt].func);
+               if (ret)
+                       break;
+       }
+
+       if (ret) {
+               /* revert the already done pin settings */
+               for (cnt--; cnt >= 0; cnt--)
+                       rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+
+               return ret;
        }
 
        return 0;
@@ -607,7 +619,7 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
        struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
        struct rockchip_pin_bank *bank;
        struct gpio_chip *chip;
-       int pin;
+       int pin, ret;
        u32 data;
 
        chip = range->gc;
@@ -617,7 +629,9 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
        dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
                 offset, range->name, pin, input ? "input" : "output");
 
-       rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+       ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+       if (ret < 0)
+               return ret;
 
        data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
        /* set bit to 1 for output, 0 for input */
@@ -1144,9 +1158,13 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
        u32 polarity;
        u32 level;
        u32 data;
+       int ret;
 
        /* make sure the pin is configured as gpio input */
-       rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+       ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+       if (ret < 0)
+               return ret;
+
        data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
        data &= ~mask;
        writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);