aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-rockchip.c
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2017-12-12 09:43:43 -0800
committerLinus Walleij <linus.walleij@linaro.org>2017-12-20 09:00:13 +0100
commit5c9d8c4f6b8168738a26bcf288516cc3a0886810 (patch)
treec1f1cbf8003c7eb1ab843b7e467b5f254758d65a /drivers/pinctrl/pinctrl-rockchip.c
parentpinctrl: mediatek: update MAINTAINERS entry with MediaTek pinctrl driver (diff)
downloadlinux-dev-5c9d8c4f6b8168738a26bcf288516cc3a0886810.tar.xz
linux-dev-5c9d8c4f6b8168738a26bcf288516cc3a0886810.zip
pinctrl: rockchip: enable clock when reading pin direction register
We generally leave the GPIO clock disabled, unless an interrupt is requested or we're accessing IO registers. We forgot to do this for the ->get_direction() callback, which means we can sometimes [1] get incorrect results [2] from, e.g., /sys/kernel/debug/gpio. Enable the clock, so we get the right results! [1] Sometimes, because many systems have 1 or mor interrupt requested on each GPIO bank, so they always leave their clock on. [2] Incorrect, meaning the register returns 0, and so we interpret that as "input". Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 2ba17548ad5b..073de6a9ed34 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2014,8 +2014,16 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
{
struct rockchip_pin_bank *bank = gpiochip_get_data(chip);
u32 data;
+ int ret;
+ ret = clk_enable(bank->clk);
+ if (ret < 0) {
+ dev_err(bank->drvdata->dev,
+ "failed to enable clock for bank %s\n", bank->name);
+ return ret;
+ }
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
+ clk_disable(bank->clk);
return !(data & BIT(offset));
}