diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/pinctrl.c | 19 | ||||
-rw-r--r-- | drivers/pinctrl/core.c | 61 |
2 files changed, 80 insertions, 0 deletions
diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index 67a274e86727..5fb74b43848e 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -48,6 +48,25 @@ int pinctrl_bind_pins(struct device *dev) goto cleanup_get; } +#ifdef CONFIG_PM + /* + * If power management is enabled, we also look for the optional + * sleep and idle pin states, with semantics as defined in + * <linux/pinctrl/pinctrl-state.h> + */ + dev->pins->sleep_state = pinctrl_lookup_state(dev->pins->p, + PINCTRL_STATE_SLEEP); + if (IS_ERR(dev->pins->sleep_state)) + /* Not supplying this state is perfectly legal */ + dev_dbg(dev, "no sleep pinctrl state\n"); + + dev->pins->idle_state = pinctrl_lookup_state(dev->pins->p, + PINCTRL_STATE_IDLE); + if (IS_ERR(dev->pins->idle_state)) + /* Not supplying this state is perfectly legal */ + dev_dbg(dev, "no idle pinctrl state\n"); +#endif + return 0; /* diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 1f9608bd237e..dca9208f5463 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1196,6 +1196,67 @@ int pinctrl_force_default(struct pinctrl_dev *pctldev) } EXPORT_SYMBOL_GPL(pinctrl_force_default); +#ifdef CONFIG_PM + +/** + * pinctrl_pm_select_default_state() - select default pinctrl state for PM + * @dev: device to select default state for + */ +int pinctrl_pm_select_default_state(struct device *dev) +{ + struct dev_pin_info *pins = dev->pins; + int ret; + + if (!pins) + return 0; + if (IS_ERR(pins->default_state)) + return 0; /* No default state */ + ret = pinctrl_select_state(pins->p, pins->default_state); + if (ret) + dev_err(dev, "failed to activate default pinctrl state\n"); + return ret; +} + +/** + * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM + * @dev: device to select sleep state for + */ +int pinctrl_pm_select_sleep_state(struct device *dev) +{ + struct dev_pin_info *pins = dev->pins; + int ret; + + if (!pins) + return 0; + if (IS_ERR(pins->sleep_state)) + return 0; /* No sleep state */ + ret = pinctrl_select_state(pins->p, pins->sleep_state); + if (ret) + dev_err(dev, "failed to activate pinctrl sleep state\n"); + return ret; +} + +/** + * pinctrl_pm_select_idle_state() - select idle pinctrl state for PM + * @dev: device to select idle state for + */ +int pinctrl_pm_select_idle_state(struct device *dev) +{ + struct dev_pin_info *pins = dev->pins; + int ret; + + if (!pins) + return 0; + if (IS_ERR(pins->idle_state)) + return 0; /* No idle state */ + ret = pinctrl_select_state(pins->p, pins->idle_state); + if (ret) + dev_err(dev, "failed to activate pinctrl idle state\n"); + return ret; +} + +#endif + #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) |