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

drivers/pinctrl: Add the concept of an "init" state

For pinctrl the "default" state is applied to pins before the driver's
probe function is called. This is normally a sensible thing to do,
but in some cases can cause problems. That's because the pins will
change state before the driver is given a chance to program how those
pins should behave.

As an example you might have a regulator that is controlled by a PWM
(output high = high voltage, output low = low voltage). The firmware
might leave this pin as driven high. If we allow the driver core to
reconfigure this pin as a PWM pin before the PWM's probe function runs
then you might end up running at too low of a voltage while we probe.

Let's introudce a new "init" state. If this is defined we'll set
pinctrl to this state before probe and then "default" after probe
(unless the driver explicitly changed states already).

An alternative idea that was thought of was to use the pre-existing
"sleep" or "idle" states and add a boolean property that we should
start in that mode. This was not done because the "init" state is
needed for correctness and those other states are only present (and
only transitioned in to and out of) when (optional) power management
is enabled.

Changes in v3:
- Moved declarations to pinctrl/devinfo.h
- Fixed author/SoB

Changes in v2:
- Added comment to pinctrl_init_done() as per Linus W.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Caesar Wang <wxt@rock-chips.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Douglas Anderson and committed by
Linus Walleij
ef0eebc0 bac7f4c1

+65 -2
+2
drivers/base/dd.c
··· 322 322 goto probe_failed; 323 323 } 324 324 325 + pinctrl_init_done(dev); 326 + 325 327 if (dev->pm_domain && dev->pm_domain->sync) 326 328 dev->pm_domain->sync(dev); 327 329
+13 -2
drivers/base/pinctrl.c
··· 42 42 goto cleanup_get; 43 43 } 44 44 45 - ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state); 45 + dev->pins->init_state = pinctrl_lookup_state(dev->pins->p, 46 + PINCTRL_STATE_INIT); 47 + if (IS_ERR(dev->pins->init_state)) { 48 + /* Not supplying this state is perfectly legal */ 49 + dev_dbg(dev, "no init pinctrl state\n"); 50 + 51 + ret = pinctrl_select_state(dev->pins->p, 52 + dev->pins->default_state); 53 + } else { 54 + ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state); 55 + } 56 + 46 57 if (ret) { 47 - dev_dbg(dev, "failed to activate default pinctrl state\n"); 58 + dev_dbg(dev, "failed to activate initial pinctrl state\n"); 48 59 goto cleanup_get; 49 60 } 50 61
+32
drivers/pinctrl/core.c
··· 1240 1240 } 1241 1241 EXPORT_SYMBOL_GPL(pinctrl_force_default); 1242 1242 1243 + /** 1244 + * pinctrl_init_done() - tell pinctrl probe is done 1245 + * 1246 + * We'll use this time to switch the pins from "init" to "default" unless the 1247 + * driver selected some other state. 1248 + * 1249 + * @dev: device to that's done probing 1250 + */ 1251 + int pinctrl_init_done(struct device *dev) 1252 + { 1253 + struct dev_pin_info *pins = dev->pins; 1254 + int ret; 1255 + 1256 + if (!pins) 1257 + return 0; 1258 + 1259 + if (IS_ERR(pins->init_state)) 1260 + return 0; /* No such state */ 1261 + 1262 + if (pins->p->state != pins->init_state) 1263 + return 0; /* Not at init anyway */ 1264 + 1265 + if (IS_ERR(pins->default_state)) 1266 + return 0; /* No default state */ 1267 + 1268 + ret = pinctrl_select_state(pins->p, pins->default_state); 1269 + if (ret) 1270 + dev_err(dev, "failed to activate default pinctrl state\n"); 1271 + 1272 + return ret; 1273 + } 1274 + 1243 1275 #ifdef CONFIG_PM 1244 1276 1245 1277 /**
+10
include/linux/pinctrl/devinfo.h
··· 24 24 * struct dev_pin_info - pin state container for devices 25 25 * @p: pinctrl handle for the containing device 26 26 * @default_state: the default state for the handle, if found 27 + * @init_state: the state at probe time, if found 28 + * @sleep_state: the state at suspend time, if found 29 + * @idle_state: the state at idle (runtime suspend) time, if found 27 30 */ 28 31 struct dev_pin_info { 29 32 struct pinctrl *p; 30 33 struct pinctrl_state *default_state; 34 + struct pinctrl_state *init_state; 31 35 #ifdef CONFIG_PM 32 36 struct pinctrl_state *sleep_state; 33 37 struct pinctrl_state *idle_state; ··· 39 35 }; 40 36 41 37 extern int pinctrl_bind_pins(struct device *dev); 38 + extern int pinctrl_init_done(struct device *dev); 42 39 43 40 #else 44 41 45 42 /* Stubs if we're not using pinctrl */ 46 43 47 44 static inline int pinctrl_bind_pins(struct device *dev) 45 + { 46 + return 0; 47 + } 48 + 49 + static inline int pinctrl_init_done(struct device *dev) 48 50 { 49 51 return 0; 50 52 }
+8
include/linux/pinctrl/pinctrl-state.h
··· 9 9 * hogs to configure muxing and pins at boot, and also as a state 10 10 * to go into when returning from sleep and idle in 11 11 * .pm_runtime_resume() or ordinary .resume() for example. 12 + * @PINCTRL_STATE_INIT: normally the pinctrl will be set to "default" 13 + * before the driver's probe() function is called. There are some 14 + * drivers where that is not appropriate becausing doing so would 15 + * glitch the pins. In those cases you can add an "init" pinctrl 16 + * which is the state of the pins before drive probe. After probe 17 + * if the pins are still in "init" state they'll be moved to 18 + * "default". 12 19 * @PINCTRL_STATE_IDLE: the state the pinctrl handle shall be put into 13 20 * when the pins are idle. This is a state where the system is relaxed 14 21 * but not fully sleeping - some power may be on but clocks gated for ··· 27 20 * ordinary .suspend() function. 28 21 */ 29 22 #define PINCTRL_STATE_DEFAULT "default" 23 + #define PINCTRL_STATE_INIT "init" 30 24 #define PINCTRL_STATE_IDLE "idle" 31 25 #define PINCTRL_STATE_SLEEP "sleep"