[PATCH] pinctrl: samsung: add pinctrl_force_sleep() for "sleep" pinctrl state
Tomasz Figa
tomasz.figa at gmail.com
Thu Sep 21 09:14:45 PDT 2017
Hi Youngmin,
2017-09-21 21:32 GMT+09:00 남영민 <youngmin.nam at samsung.com>:
> This patch adds pinctrl_for_sleep() in samsung_pinctrl_suspend()
> to support configuration of "sleep" pinctrl state.
>
> For example, we can configure "sleep" pinctrl state of "gpf1-6"
> as "INPUT, PULL DOWN" by configuring power down mode register.
>
> &pinctrl_5 {
> pinctrl-names = "default","sleep";
> pinctrl-0 = <&initial5>;
> pinctrl-1 = <&sleep5>;
>
> initial5: initial-state {
> samsung,pins = gpf1-6;
> samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> };
> sleep5: sleep-state {
> samsung,pins = gpf1-6;
> samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
> samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_DOWN>;
This isn't a very good example, because pin-con-pdn and pin-pud-pdn
are used to program dedicated sleep state registers in the pin
controller and they can be programmed at any time. Typically one would
include them in "default" state.
As for pins which don't have dedicated sleep state registers, i.e. the
alive banks, which retain their value, the DT node of device
associated with the pins would have "sleep" pinctrl state and its
driver would activate it on suspend.
The only remaining use case would be pins in alive banks not
associated with any device, but I can't imagine any practical case
that would need to change the value on suspend in such case.
Do you have an example of a real use case for this patch?
> };
> };
>
> Signed-off-by: Youngmin Nam <youngmin.nam at samsung.com>
> ---
> drivers/pinctrl/samsung/pinctrl-samsung.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index e04f7fe0a65d..b4d12f8db475 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1099,6 +1099,11 @@ static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)
> {
> struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);
> int i;
> + int ret;
> +
> + ret = pinctrl_force_sleep(drvdata->pctl_dev);
> + if (ret)
> + dev_err(dev, "could not set sleep pinstate %d\n", ret);
>
> for (i = 0; i < drvdata->nr_banks; i++) {
> struct samsung_pin_bank *bank = &drvdata->pin_banks[i];
> @@ -1187,6 +1192,11 @@ static int __maybe_unused samsung_pinctrl_resume(struct device *dev)
> if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable)
> drvdata->retention_ctrl->disable(drvdata);
>
> + /* For changing state without writing register. */
> + if (!IS_ERR(drvdata->pctl_dev->p) &&
> + !IS_ERR(drvdata->pctl_dev->hog_default))
> + drvdata->pctl_dev->p->state = drvdata->pctl_dev->hog_default;
How is this supposed to work? The pins were reconfigured at suspend,
where are they restored back to the values before suspend?
Best regards,
Tomasz
More information about the linux-arm-kernel
mailing list