This patch adds support for parsing following regulator contraints from device tree blob. 1. valid modes mask (valid_modes_mask) 2. initial mode (initial_mode) 3. initial state (initial_state) 4. state mem (state_mem) 5. state disk (state_disk) 6. state standby (state_standby) Signed-off-by: Saurabh Singh Sengar <saurabh1.s@xxxxxxxxxxx> --- .../devicetree/bindings/regulator/regulator.txt | 45 ++++++++++++ drivers/regulator/of_regulator.c | 77 ++++++++++++++++++++ 2 files changed, 122 insertions(+), 0 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 2bd8f09..6dc935b 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -14,6 +14,36 @@ Optional properties: - regulator-ramp-delay: ramp delay for regulator(in uV/uS) For hardwares which support disabling ramp rate, it should be explicitly intialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay. +- regulator-valid-modes-mask: valid operations for regulator on particular machine + Supports following modes of operations: + Mode Description + ---- ----------- + fast Regulator can handle fast changes in it's load + normal Normal regulator power supply mode + idle Regulator runs in a more efficient mode for light loads. + standby Regulator runs in the most efficient mode for very light loads + See the example given below. + +- regulator-initial-mode: default mode to set on startup + Refer to regulator-initial-mode for modes supported + +- regulator-initial-state: suspend state to set at init + Any one of the following states can be set: + Mode Description + ---- ----------- + suspend-mem suspend to memory + suspend-standby standby mode + suspend-disk suspend to disk + See the example given below. + +- regulator-state-mem, regulator-state-disk, regulator-state-standby: + defines regulator suspend to memory, suspend to disk (hibernate) and standby respectively. + have following sub-constarints: + - regulator-state-uv: voltage to set in suspend state + - regulator-state-mode: suspend regulator operating mode, + refer to regulator-valid-modes-mask for modes supported + - regulator-state-enabled: is regulator enabled in this suspend state + - regulator-state-disabled: is the regulator disbled in this suspend state Deprecated properties: - regulator-compatible: If a regulator chip contains multiple @@ -29,6 +59,21 @@ Example: regulator-max-microvolt = <2500000>; regulator-always-on; vin-supply = <&vin>; + regulator-initial-mode = "normal"; + regulator-initial-state = "suspend-mem"; + regulator-valid-modes-mask { + /*can support multiple mode + * in this example supporting fast and normal mode */ + fast-mode; + normal-mode; + }; + regulator-state-mem { + regulator-state-mode = "idle"; + regulator-state-enabled; + }; + regulator-state-disk { + regulator-state-disabled; + }; }; Regulator Consumers: diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 7827384..3030597 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -16,11 +16,36 @@ #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> +/** + * set_regulator_state_constraints - set regulator state for low power system states + * @np: device node for the low power regulator state + * @regulator_state: regulator_state structure need to be filled + */ +static void set_regulator_state_constraints(struct device_node *np, + struct regulator_state *state) +{ + of_property_read_u32(np, "regulator-state-uv", &state->uV); + if (!of_property_match_string(np, "regulator-state-mode", "fast")) + state->mode = REGULATOR_MODE_FAST; + else if (!of_property_match_string(np, "regulator-state-mode", + "normal")) + state->mode = REGULATOR_MODE_NORMAL; + else if (!of_property_match_string(np, "regulator-state-mode", "idle")) + state->mode = REGULATOR_MODE_IDLE; + else if (!of_property_match_string(np, "regulator-state-mode", + "standby")) + state->mode = REGULATOR_MODE_STANDBY; + state->enabled = of_property_read_bool(np, "regulator-state-enabled"); + state->disabled = of_property_read_bool(np, "regulator-state-disabled"); +} + + static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) { const __be32 *min_uV, *max_uV, *uV_offset; const __be32 *min_uA, *max_uA, *ramp_delay; + struct device_node *state, *valid_modes; struct property *prop; struct regulation_constraints *constraints = &(*init_data)->constraints; @@ -73,6 +98,58 @@ static void of_get_regulation_constraints(struct device_node *np, else constraints->ramp_disable = true; } + + valid_modes = of_find_node_by_name(np, "regulator-valid-modes-mask"); + if (valid_modes) { + if (of_property_read_bool(valid_modes, "fast")) + constraints->valid_modes_mask = REGULATOR_MODE_FAST; + if (of_property_read_bool(valid_modes, "normal")) + constraints->valid_modes_mask |= REGULATOR_MODE_NORMAL; + if (of_property_read_bool(valid_modes, "idle")) + constraints->valid_modes_mask |= REGULATOR_MODE_IDLE; + if (of_property_read_bool(valid_modes, "standby")) + constraints->valid_modes_mask |= REGULATOR_MODE_STANDBY; + } + + /* flag assignment for initial mode*/ + if (!of_property_match_string(np, "regulator-initial-mode", "fast")) + constraints->initial_mode = REGULATOR_MODE_FAST; + else if (!of_property_match_string(np, "regulator-initial-mode", + "normal")) + constraints->initial_mode = REGULATOR_MODE_NORMAL; + else if (!of_property_match_string(np, "regulator-initial-mode", + "idle")) + constraints->initial_mode = REGULATOR_MODE_IDLE; + else if (!of_property_match_string(np, "regulator-initial-mode", + "standby")) + constraints->initial_mode = REGULATOR_MODE_STANDBY; + + /* flag assignment for initial state*/ + if (!of_property_match_string(np, + "regulator-initial-state", "suspend-mem")) + constraints->initial_state = PM_SUSPEND_MEM; + else if (!of_property_match_string(np, + "regulator-initial-state", "suspend-standby")) + constraints->initial_state = PM_SUSPEND_STANDBY; + else if (!of_property_match_string(np, + "regulator-initial-state", "suspend-disk")) + constraints->initial_state = PM_SUSPEND_MAX; + + /* regulator state during low power system states */ + state = of_find_node_by_name(np, "regulator-state-mem"); + if (state) + set_regulator_state_constraints(state, + &constraints->state_mem); + + state = of_find_node_by_name(np, "regulator-state-disk"); + if (state) + set_regulator_state_constraints(state, + &constraints->state_disk); + + state = of_find_node_by_name(np, "regulator-state-standby"); + if (state) + set_regulator_state_constraints(state, + &constraints->state_standby); } /** -- 1.7.0.4ÿôèº{.nÇ+‰·Ÿ®‰†+%ŠËÿ±éݶ¥Šwÿº{.nÇ+‰·?zøœzÚÞ{ø§¶›¡Ü¨}©ž²Æ zÚ&j:+v‰¨þø¯ù®w¥þŠà2ŠÞ™¨èÚ&¢)ß¡«a¶Úÿÿûàz¿äz¹Þ—ú+ƒùšŽŠÝ¢jÿŠwèþf