The regulation_constraints structure includes specific field to support suspend state for global PMIC STANDBY/HIBERNATE mode. This patch add support for parsing regulator_state for suspend state. Signed-off-by: Chanwoo Choi <cw00.choi@xxxxxxxxxxx> --- drivers/regulator/of_regulator.c | 76 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index ee5e67b..cf280ab 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -16,12 +16,20 @@ #include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> +const char *const regulator_states[PM_SUSPEND_MAX + 1] = { + [PM_SUSPEND_STANDBY] = "regulator-state-standby", + [PM_SUSPEND_MEM] = "regulator-state-mem", + [PM_SUSPEND_MAX] = "regulator-state-disk", +}; + static void of_get_regulation_constraints(struct device_node *np, struct regulator_init_data **init_data) { - const __be32 *min_uV, *max_uV; + const __be32 *min_uV, *max_uV, *suspend_uV; struct regulation_constraints *constraints = &(*init_data)->constraints; - int ret; + struct regulator_state *suspend_state; + struct device_node *suspend_np; + int ret, i; u32 pval; constraints->name = of_get_property(np, "regulator-name", NULL); @@ -70,6 +78,70 @@ static void of_get_regulation_constraints(struct device_node *np, ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval); if (!ret) constraints->enable_time = pval; + + ret = of_property_read_u32(np, "regulator-initial-state", &pval); + if (!ret) { + switch (pval) { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + case PM_SUSPEND_MAX: + constraints->initial_state = pval; + break; + default: + break; + }; + } + + for (i = 0; i < ARRAY_SIZE(regulator_states); i++) { + switch (i) { + case PM_SUSPEND_STANDBY: + suspend_state = &constraints->state_standby; + break; + case PM_SUSPEND_MEM: + suspend_state = &constraints->state_mem; + break; + case PM_SUSPEND_MAX: + suspend_state = &constraints->state_disk; + break; + case PM_SUSPEND_ON: + case PM_SUSPEND_FREEZE: + default: + continue; + }; + + suspend_np = of_get_child_by_name(np, regulator_states[i]); + if (!suspend_np || !suspend_state) + continue; + + suspend_uV = of_get_property(suspend_np, "regulator-volt", NULL); + if (suspend_uV) { + suspend_state->uV = be32_to_cpu(*suspend_uV); + + if (suspend_state->uV < constraints->min_uV) + suspend_state->uV = constraints->min_uV; + if (suspend_state->uV > constraints->max_uV) + suspend_state->uV = constraints->max_uV; + } + + ret = of_property_read_u32(suspend_np, "regulator-mode", &pval); + if (!ret) { + u32 regulator_mode = REGULATOR_MODE_FAST + | REGULATOR_MODE_NORMAL + | REGULATOR_MODE_IDLE + | REGULATOR_MODE_STANDBY; + if (pval <= regulator_mode) + suspend_state->mode = pval; + } + + if (of_property_read_bool(suspend_np, "regulator-on-in-suspend")) + suspend_state->enabled = true; + + if (of_property_read_bool(suspend_np, "regulator-off-in-suspend")) + suspend_state->disabled = true; + + suspend_state = NULL; + suspend_np = NULL; + } } /** -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html