Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: pinctrl sleep and idle states in the core

If a device have sleep and idle states in addition to the
default state, look up these in the core and stash them in
the pinctrl state container.

Add accessor functions for pinctrl consumers to put the pins
into "default", "sleep" and "idle" states passing nothing but
the struct device * affected.

Solution suggested by Kevin Hilman, Mark Brown and Dmitry
Torokhov in response to a patch series from Hebbar
Gururaja.

Cc: Hebbar Gururaja <gururaja.hebbar@ti.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

+118
+19
drivers/base/pinctrl.c
··· 48 48 goto cleanup_get; 49 49 } 50 50 51 + #ifdef CONFIG_PM 52 + /* 53 + * If power management is enabled, we also look for the optional 54 + * sleep and idle pin states, with semantics as defined in 55 + * <linux/pinctrl/pinctrl-state.h> 56 + */ 57 + dev->pins->sleep_state = pinctrl_lookup_state(dev->pins->p, 58 + PINCTRL_STATE_SLEEP); 59 + if (IS_ERR(dev->pins->sleep_state)) 60 + /* Not supplying this state is perfectly legal */ 61 + dev_dbg(dev, "no sleep pinctrl state\n"); 62 + 63 + dev->pins->idle_state = pinctrl_lookup_state(dev->pins->p, 64 + PINCTRL_STATE_IDLE); 65 + if (IS_ERR(dev->pins->idle_state)) 66 + /* Not supplying this state is perfectly legal */ 67 + dev_dbg(dev, "no idle pinctrl state\n"); 68 + #endif 69 + 51 70 return 0; 52 71 53 72 /*
+61
drivers/pinctrl/core.c
··· 1196 1196 } 1197 1197 EXPORT_SYMBOL_GPL(pinctrl_force_default); 1198 1198 1199 + #ifdef CONFIG_PM 1200 + 1201 + /** 1202 + * pinctrl_pm_select_default_state() - select default pinctrl state for PM 1203 + * @dev: device to select default state for 1204 + */ 1205 + int pinctrl_pm_select_default_state(struct device *dev) 1206 + { 1207 + struct dev_pin_info *pins = dev->pins; 1208 + int ret; 1209 + 1210 + if (!pins) 1211 + return 0; 1212 + if (IS_ERR(pins->default_state)) 1213 + return 0; /* No default state */ 1214 + ret = pinctrl_select_state(pins->p, pins->default_state); 1215 + if (ret) 1216 + dev_err(dev, "failed to activate default pinctrl state\n"); 1217 + return ret; 1218 + } 1219 + 1220 + /** 1221 + * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM 1222 + * @dev: device to select sleep state for 1223 + */ 1224 + int pinctrl_pm_select_sleep_state(struct device *dev) 1225 + { 1226 + struct dev_pin_info *pins = dev->pins; 1227 + int ret; 1228 + 1229 + if (!pins) 1230 + return 0; 1231 + if (IS_ERR(pins->sleep_state)) 1232 + return 0; /* No sleep state */ 1233 + ret = pinctrl_select_state(pins->p, pins->sleep_state); 1234 + if (ret) 1235 + dev_err(dev, "failed to activate pinctrl sleep state\n"); 1236 + return ret; 1237 + } 1238 + 1239 + /** 1240 + * pinctrl_pm_select_idle_state() - select idle pinctrl state for PM 1241 + * @dev: device to select idle state for 1242 + */ 1243 + int pinctrl_pm_select_idle_state(struct device *dev) 1244 + { 1245 + struct dev_pin_info *pins = dev->pins; 1246 + int ret; 1247 + 1248 + if (!pins) 1249 + return 0; 1250 + if (IS_ERR(pins->idle_state)) 1251 + return 0; /* No idle state */ 1252 + ret = pinctrl_select_state(pins->p, pins->idle_state); 1253 + if (ret) 1254 + dev_err(dev, "failed to activate pinctrl idle state\n"); 1255 + return ret; 1256 + } 1257 + 1258 + #endif 1259 + 1199 1260 #ifdef CONFIG_DEBUG_FS 1200 1261 1201 1262 static int pinctrl_pins_show(struct seq_file *s, void *what)
+34
include/linux/pinctrl/consumer.h
··· 40 40 extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev); 41 41 extern void devm_pinctrl_put(struct pinctrl *p); 42 42 43 + #ifdef CONFIG_PM 44 + extern int pinctrl_pm_select_default_state(struct device *dev); 45 + extern int pinctrl_pm_select_sleep_state(struct device *dev); 46 + extern int pinctrl_pm_select_idle_state(struct device *dev); 47 + #else 48 + static inline int pinctrl_pm_select_default_state(struct device *dev) 49 + { 50 + return 0; 51 + } 52 + static inline int pinctrl_pm_select_sleep_state(struct device *dev) 53 + { 54 + return 0; 55 + } 56 + static inline int pinctrl_pm_select_idle_state(struct device *dev) 57 + { 58 + return 0; 59 + } 60 + #endif 61 + 43 62 #else /* !CONFIG_PINCTRL */ 44 63 45 64 static inline int pinctrl_request_gpio(unsigned gpio) ··· 214 195 static inline int pin_config_group_set(const char *dev_name, 215 196 const char *pin_group, 216 197 unsigned long config) 198 + { 199 + return 0; 200 + } 201 + 202 + static inline int pinctrl_pm_select_default_state(struct device *dev) 203 + { 204 + return 0; 205 + } 206 + 207 + static inline int pinctrl_pm_select_sleep_state(struct device *dev) 208 + { 209 + return 0; 210 + } 211 + 212 + static inline int pinctrl_pm_select_idle_state(struct device *dev) 217 213 { 218 214 return 0; 219 215 }
+4
include/linux/pinctrl/devinfo.h
··· 28 28 struct dev_pin_info { 29 29 struct pinctrl *p; 30 30 struct pinctrl_state *default_state; 31 + #ifdef CONFIG_PM 32 + struct pinctrl_state *sleep_state; 33 + struct pinctrl_state *idle_state; 34 + #endif 31 35 }; 32 36 33 37 extern int pinctrl_bind_pins(struct device *dev);