aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-06-05 09:30:33 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:46 -0400
commite424dbaf675ed83003e8a33ef962e38217995d2e (patch)
tree56fc82ff04d0b201927ef3c401f1db2ed447697e
parentc8013d610d9864836feb17d5cacbddc5eb16d69f (diff)
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>
-rw-r--r--drivers/base/pinctrl.c19
-rw-r--r--drivers/pinctrl/core.c61
-rw-r--r--include/linux/pinctrl/consumer.h34
-rw-r--r--include/linux/pinctrl/devinfo.h4
4 files changed, 118 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)
48 goto cleanup_get; 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 return 0; 70 return 0;
52 71
53 /* 72 /*
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index bb7ee9cb00b1..fbeb2c1f7be6 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1206,6 +1206,67 @@ int pinctrl_force_default(struct pinctrl_dev *pctldev)
1206} 1206}
1207EXPORT_SYMBOL_GPL(pinctrl_force_default); 1207EXPORT_SYMBOL_GPL(pinctrl_force_default);
1208 1208
1209#ifdef CONFIG_PM
1210
1211/**
1212 * pinctrl_pm_select_default_state() - select default pinctrl state for PM
1213 * @dev: device to select default state for
1214 */
1215int pinctrl_pm_select_default_state(struct device *dev)
1216{
1217 struct dev_pin_info *pins = dev->pins;
1218 int ret;
1219
1220 if (!pins)
1221 return 0;
1222 if (IS_ERR(pins->default_state))
1223 return 0; /* No default state */
1224 ret = pinctrl_select_state(pins->p, pins->default_state);
1225 if (ret)
1226 dev_err(dev, "failed to activate default pinctrl state\n");
1227 return ret;
1228}
1229
1230/**
1231 * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM
1232 * @dev: device to select sleep state for
1233 */
1234int pinctrl_pm_select_sleep_state(struct device *dev)
1235{
1236 struct dev_pin_info *pins = dev->pins;
1237 int ret;
1238
1239 if (!pins)
1240 return 0;
1241 if (IS_ERR(pins->sleep_state))
1242 return 0; /* No sleep state */
1243 ret = pinctrl_select_state(pins->p, pins->sleep_state);
1244 if (ret)
1245 dev_err(dev, "failed to activate pinctrl sleep state\n");
1246 return ret;
1247}
1248
1249/**
1250 * pinctrl_pm_select_idle_state() - select idle pinctrl state for PM
1251 * @dev: device to select idle state for
1252 */
1253int pinctrl_pm_select_idle_state(struct device *dev)
1254{
1255 struct dev_pin_info *pins = dev->pins;
1256 int ret;
1257
1258 if (!pins)
1259 return 0;
1260 if (IS_ERR(pins->idle_state))
1261 return 0; /* No idle state */
1262 ret = pinctrl_select_state(pins->p, pins->idle_state);
1263 if (ret)
1264 dev_err(dev, "failed to activate pinctrl idle state\n");
1265 return ret;
1266}
1267
1268#endif
1269
1209#ifdef CONFIG_DEBUG_FS 1270#ifdef CONFIG_DEBUG_FS
1210 1271
1211static int pinctrl_pins_show(struct seq_file *s, void *what) 1272static int pinctrl_pins_show(struct seq_file *s, void *what)
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
index 4aad3cea69ae..0f32f10e347d 100644
--- a/include/linux/pinctrl/consumer.h
+++ b/include/linux/pinctrl/consumer.h
@@ -40,6 +40,25 @@ extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);
40extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev); 40extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev);
41extern void devm_pinctrl_put(struct pinctrl *p); 41extern void devm_pinctrl_put(struct pinctrl *p);
42 42
43#ifdef CONFIG_PM
44extern int pinctrl_pm_select_default_state(struct device *dev);
45extern int pinctrl_pm_select_sleep_state(struct device *dev);
46extern int pinctrl_pm_select_idle_state(struct device *dev);
47#else
48static inline int pinctrl_pm_select_default_state(struct device *dev)
49{
50 return 0;
51}
52static inline int pinctrl_pm_select_sleep_state(struct device *dev)
53{
54 return 0;
55}
56static inline int pinctrl_pm_select_idle_state(struct device *dev)
57{
58 return 0;
59}
60#endif
61
43#else /* !CONFIG_PINCTRL */ 62#else /* !CONFIG_PINCTRL */
44 63
45static inline int pinctrl_request_gpio(unsigned gpio) 64static inline int pinctrl_request_gpio(unsigned gpio)
@@ -199,6 +218,21 @@ static inline int pin_config_group_set(const char *dev_name,
199 return 0; 218 return 0;
200} 219}
201 220
221static inline int pinctrl_pm_select_default_state(struct device *dev)
222{
223 return 0;
224}
225
226static inline int pinctrl_pm_select_sleep_state(struct device *dev)
227{
228 return 0;
229}
230
231static inline int pinctrl_pm_select_idle_state(struct device *dev)
232{
233 return 0;
234}
235
202#endif 236#endif
203 237
204#endif /* __LINUX_PINCTRL_CONSUMER_H */ 238#endif /* __LINUX_PINCTRL_CONSUMER_H */
diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h
index 6e5f8a985ea7..281cb91ddcf5 100644
--- a/include/linux/pinctrl/devinfo.h
+++ b/include/linux/pinctrl/devinfo.h
@@ -28,6 +28,10 @@
28struct dev_pin_info { 28struct dev_pin_info {
29 struct pinctrl *p; 29 struct pinctrl *p;
30 struct pinctrl_state *default_state; 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
33extern int pinctrl_bind_pins(struct device *dev); 37extern int pinctrl_bind_pins(struct device *dev);