diff options
author | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 2019-08-08 15:19:03 +0900 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2019-08-23 09:08:10 +0200 |
commit | 8a0cc47ccc7c17826c669787f95ab7e5efb37444 (patch) | |
tree | 4cf08c95071155441c1b401bc80528394d468f22 /drivers/pinctrl/sh-pfc | |
parent | b13431ed6eab808affbd796a7c8caf05c7ae4cdd (diff) |
pinctrl: sh-pfc: Rollback to mux if required when the gpio is freed
Some drivers require switching between function and gpio at run-time.
Allow to roll back from gpio to mux when the gpio is freed.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Diffstat (limited to 'drivers/pinctrl/sh-pfc')
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index ab2aa93dd73b..99f4ebd69861 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -26,6 +26,7 @@ #include "../pinconf.h" struct sh_pfc_pin_config { + unsigned int mux_mark; bool mux_set; bool gpio_enabled; }; @@ -353,6 +354,16 @@ static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector, spin_lock_irqsave(&pfc->lock, flags); for (i = 0; i < grp->nr_pins; ++i) { + int idx = sh_pfc_get_pin_index(pfc, grp->pins[i]); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + + /* + * This driver cannot manage both gpio and mux when the gpio + * pin is already enabled. So, this function fails. + */ + if (cfg->gpio_enabled) + return -EBUSY; + ret = sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION); if (ret < 0) goto done; @@ -364,6 +375,7 @@ static int sh_pfc_func_set_mux(struct pinctrl_dev *pctldev, unsigned selector, struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; cfg->mux_set = true; + cfg->mux_mark = grp->mux[i]; } done: @@ -417,6 +429,9 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pfc->lock, flags); cfg->gpio_enabled = false; + /* If mux is already set, this configures it here */ + if (cfg->mux_set) + sh_pfc_config_mux(pfc, cfg->mux_mark, PINMUX_TYPE_FUNCTION); spin_unlock_irqrestore(&pfc->lock, flags); } |