summaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2017-12-12 09:43:43 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-24 11:01:26 +0100
commit915bd53d68f675ff046672f54e3a3de3b8131981 (patch)
tree350bcfc0576a7bd8e712d13459ff865a7dc8c341 /drivers/pinctrl
parent130e535210ba861d46c43441e696aa73f2370a05 (diff)
pinctrl: rockchip: enable clock when reading pin direction register
[ Upstream commit 5c9d8c4f6b8168738a26bcf288516cc3a0886810 ] 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> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pinctrl')
-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 b5cb7858ffdc..a9bc1e01f982 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -1989,8 +1989,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));
}