aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-01-26 12:40:03 -0500
committerMark Brown <broonie@kernel.org>2018-01-26 12:40:03 -0500
commit285c22de377dd6895af30af6272cc7778cee36a7 (patch)
tree0242402441f35cf83afea2c7054d5174ae12fc79
parent3d67fe950707a930664c5673ecc026f1bb497136 (diff)
parentf7efad10b5c492892b1e5decf5d3ebb29fa5c9af (diff)
Merge branch 'topic/suspend' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into regulator-core
-rw-r--r--Documentation/devicetree/bindings/regulator/regulator.txt12
-rw-r--r--drivers/regulator/core.c346
-rw-r--r--drivers/regulator/internal.h18
-rw-r--r--drivers/regulator/of_regulator.c20
-rw-r--r--include/linux/regulator/driver.h2
-rw-r--r--include/linux/regulator/machine.h37
6 files changed, 309 insertions, 126 deletions
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
index 378f6dc8b8bd..e459226dfac9 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -42,8 +42,16 @@ Optional properties:
42- regulator-state-[mem/disk] node has following common properties: 42- regulator-state-[mem/disk] node has following common properties:
43 - regulator-on-in-suspend: regulator should be on in suspend state. 43 - regulator-on-in-suspend: regulator should be on in suspend state.
44 - regulator-off-in-suspend: regulator should be off in suspend state. 44 - regulator-off-in-suspend: regulator should be off in suspend state.
45 - regulator-suspend-microvolt: regulator should be set to this voltage 45 - regulator-suspend-min-microvolt: minimum voltage may be set in
46 in suspend. 46 suspend state.
47 - regulator-suspend-max-microvolt: maximum voltage may be set in
48 suspend state.
49 - regulator-suspend-microvolt: the default voltage which regulator
50 would be set in suspend. This property is now deprecated, instead
51 setting voltage for suspend mode via the API which regulator
52 driver provides is recommended.
53 - regulator-changeable-in-suspend: whether the default voltage and
54 the regulator on/off in suspend can be changed in runtime.
47 - regulator-mode: operating mode in the given suspend state. 55 - regulator-mode: operating mode in the given suspend state.
48 The set of possible operating modes depends on the capabilities of 56 The set of possible operating modes depends on the capabilities of
49 every hardware so the valid modes are documented on each regulator 57 every hardware so the valid modes are documented on each regulator
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index fd8eacfea422..2dccc4b3766e 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -229,26 +229,35 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
229 return 0; 229 return 0;
230} 230}
231 231
232/* return 0 if the state is valid */
233static int regulator_check_states(suspend_state_t state)
234{
235 return (state > PM_SUSPEND_MAX || state == PM_SUSPEND_TO_IDLE);
236}
237
232/* Make sure we select a voltage that suits the needs of all 238/* Make sure we select a voltage that suits the needs of all
233 * regulator consumers 239 * regulator consumers
234 */ 240 */
235static int regulator_check_consumers(struct regulator_dev *rdev, 241static int regulator_check_consumers(struct regulator_dev *rdev,
236 int *min_uV, int *max_uV) 242 int *min_uV, int *max_uV,
243 suspend_state_t state)
237{ 244{
238 struct regulator *regulator; 245 struct regulator *regulator;
246 struct regulator_voltage *voltage;
239 247
240 list_for_each_entry(regulator, &rdev->consumer_list, list) { 248 list_for_each_entry(regulator, &rdev->consumer_list, list) {
249 voltage = &regulator->voltage[state];
241 /* 250 /*
242 * Assume consumers that didn't say anything are OK 251 * Assume consumers that didn't say anything are OK
243 * with anything in the constraint range. 252 * with anything in the constraint range.
244 */ 253 */
245 if (!regulator->min_uV && !regulator->max_uV) 254 if (!voltage->min_uV && !voltage->max_uV)
246 continue; 255 continue;
247 256
248 if (*max_uV > regulator->max_uV) 257 if (*max_uV > voltage->max_uV)
249 *max_uV = regulator->max_uV; 258 *max_uV = voltage->max_uV;
250 if (*min_uV < regulator->min_uV) 259 if (*min_uV < voltage->min_uV)
251 *min_uV = regulator->min_uV; 260 *min_uV = voltage->min_uV;
252 } 261 }
253 262
254 if (*min_uV > *max_uV) { 263 if (*min_uV > *max_uV) {
@@ -317,6 +326,24 @@ static int regulator_mode_constrain(struct regulator_dev *rdev,
317 return -EINVAL; 326 return -EINVAL;
318} 327}
319 328
329static inline struct regulator_state *
330regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state)
331{
332 if (rdev->constraints == NULL)
333 return NULL;
334
335 switch (state) {
336 case PM_SUSPEND_STANDBY:
337 return &rdev->constraints->state_standby;
338 case PM_SUSPEND_MEM:
339 return &rdev->constraints->state_mem;
340 case PM_SUSPEND_MAX:
341 return &rdev->constraints->state_disk;
342 default:
343 return NULL;
344 }
345}
346
320static ssize_t regulator_uV_show(struct device *dev, 347static ssize_t regulator_uV_show(struct device *dev,
321 struct device_attribute *attr, char *buf) 348 struct device_attribute *attr, char *buf)
322{ 349{
@@ -724,29 +751,32 @@ static int drms_uA_update(struct regulator_dev *rdev)
724} 751}
725 752
726static int suspend_set_state(struct regulator_dev *rdev, 753static int suspend_set_state(struct regulator_dev *rdev,
727 struct regulator_state *rstate) 754 suspend_state_t state)
728{ 755{
729 int ret = 0; 756 int ret = 0;
757 struct regulator_state *rstate;
758
759 rstate = regulator_get_suspend_state(rdev, state);
760 if (rstate == NULL)
761 return -EINVAL;
730 762
731 /* If we have no suspend mode configration don't set anything; 763 /* If we have no suspend mode configration don't set anything;
732 * only warn if the driver implements set_suspend_voltage or 764 * only warn if the driver implements set_suspend_voltage or
733 * set_suspend_mode callback. 765 * set_suspend_mode callback.
734 */ 766 */
735 if (!rstate->enabled && !rstate->disabled) { 767 if (rstate->enabled != ENABLE_IN_SUSPEND &&
768 rstate->enabled != DISABLE_IN_SUSPEND) {
736 if (rdev->desc->ops->set_suspend_voltage || 769 if (rdev->desc->ops->set_suspend_voltage ||
737 rdev->desc->ops->set_suspend_mode) 770 rdev->desc->ops->set_suspend_mode)
738 rdev_warn(rdev, "No configuration\n"); 771 rdev_warn(rdev, "No configuration\n");
739 return 0; 772 return 0;
740 } 773 }
741 774
742 if (rstate->enabled && rstate->disabled) { 775 if (rstate->enabled == ENABLE_IN_SUSPEND &&
743 rdev_err(rdev, "invalid configuration\n"); 776 rdev->desc->ops->set_suspend_enable)
744 return -EINVAL;
745 }
746
747 if (rstate->enabled && rdev->desc->ops->set_suspend_enable)
748 ret = rdev->desc->ops->set_suspend_enable(rdev); 777 ret = rdev->desc->ops->set_suspend_enable(rdev);
749 else if (rstate->disabled && rdev->desc->ops->set_suspend_disable) 778 else if (rstate->enabled == DISABLE_IN_SUSPEND &&
779 rdev->desc->ops->set_suspend_disable)
750 ret = rdev->desc->ops->set_suspend_disable(rdev); 780 ret = rdev->desc->ops->set_suspend_disable(rdev);
751 else /* OK if set_suspend_enable or set_suspend_disable is NULL */ 781 else /* OK if set_suspend_enable or set_suspend_disable is NULL */
752 ret = 0; 782 ret = 0;
@@ -771,28 +801,8 @@ static int suspend_set_state(struct regulator_dev *rdev,
771 return ret; 801 return ret;
772 } 802 }
773 } 803 }
774 return ret;
775}
776
777/* locks held by caller */
778static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
779{
780 if (!rdev->constraints)
781 return -EINVAL;
782 804
783 switch (state) { 805 return ret;
784 case PM_SUSPEND_STANDBY:
785 return suspend_set_state(rdev,
786 &rdev->constraints->state_standby);
787 case PM_SUSPEND_MEM:
788 return suspend_set_state(rdev,
789 &rdev->constraints->state_mem);
790 case PM_SUSPEND_MAX:
791 return suspend_set_state(rdev,
792 &rdev->constraints->state_disk);
793 default:
794 return -EINVAL;
795 }
796} 806}
797 807
798static void print_constraints(struct regulator_dev *rdev) 808static void print_constraints(struct regulator_dev *rdev)
@@ -1061,7 +1071,7 @@ static int set_machine_constraints(struct regulator_dev *rdev,
1061 1071
1062 /* do we need to setup our suspend state */ 1072 /* do we need to setup our suspend state */
1063 if (rdev->constraints->initial_state) { 1073 if (rdev->constraints->initial_state) {
1064 ret = suspend_prepare(rdev, rdev->constraints->initial_state); 1074 ret = suspend_set_state(rdev, rdev->constraints->initial_state);
1065 if (ret < 0) { 1075 if (ret < 0) {
1066 rdev_err(rdev, "failed to set suspend state\n"); 1076 rdev_err(rdev, "failed to set suspend state\n");
1067 return ret; 1077 return ret;
@@ -1349,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
1349 debugfs_create_u32("uA_load", 0444, regulator->debugfs, 1359 debugfs_create_u32("uA_load", 0444, regulator->debugfs,
1350 &regulator->uA_load); 1360 &regulator->uA_load);
1351 debugfs_create_u32("min_uV", 0444, regulator->debugfs, 1361 debugfs_create_u32("min_uV", 0444, regulator->debugfs,
1352 &regulator->min_uV); 1362 &regulator->voltage[PM_SUSPEND_ON].min_uV);
1353 debugfs_create_u32("max_uV", 0444, regulator->debugfs, 1363 debugfs_create_u32("max_uV", 0444, regulator->debugfs,
1354 &regulator->max_uV); 1364 &regulator->voltage[PM_SUSPEND_ON].max_uV);
1355 debugfs_create_file("constraint_flags", 0444, 1365 debugfs_create_file("constraint_flags", 0444,
1356 regulator->debugfs, regulator, 1366 regulator->debugfs, regulator,
1357 &constraint_flags_fops); 1367 &constraint_flags_fops);
@@ -2876,10 +2886,38 @@ out:
2876 return ret; 2886 return ret;
2877} 2887}
2878 2888
2889static int _regulator_do_set_suspend_voltage(struct regulator_dev *rdev,
2890 int min_uV, int max_uV, suspend_state_t state)
2891{
2892 struct regulator_state *rstate;
2893 int uV, sel;
2894
2895 rstate = regulator_get_suspend_state(rdev, state);
2896 if (rstate == NULL)
2897 return -EINVAL;
2898
2899 if (min_uV < rstate->min_uV)
2900 min_uV = rstate->min_uV;
2901 if (max_uV > rstate->max_uV)
2902 max_uV = rstate->max_uV;
2903
2904 sel = regulator_map_voltage(rdev, min_uV, max_uV);
2905 if (sel < 0)
2906 return sel;
2907
2908 uV = rdev->desc->ops->list_voltage(rdev, sel);
2909 if (uV >= min_uV && uV <= max_uV)
2910 rstate->uV = uV;
2911
2912 return 0;
2913}
2914
2879static int regulator_set_voltage_unlocked(struct regulator *regulator, 2915static int regulator_set_voltage_unlocked(struct regulator *regulator,
2880 int min_uV, int max_uV) 2916 int min_uV, int max_uV,
2917 suspend_state_t state)
2881{ 2918{
2882 struct regulator_dev *rdev = regulator->rdev; 2919 struct regulator_dev *rdev = regulator->rdev;
2920 struct regulator_voltage *voltage = &regulator->voltage[state];
2883 int ret = 0; 2921 int ret = 0;
2884 int old_min_uV, old_max_uV; 2922 int old_min_uV, old_max_uV;
2885 int current_uV; 2923 int current_uV;
@@ -2890,7 +2928,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2890 * should be a noop (some cpufreq implementations use the same 2928 * should be a noop (some cpufreq implementations use the same
2891 * voltage for multiple frequencies, for example). 2929 * voltage for multiple frequencies, for example).
2892 */ 2930 */
2893 if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) 2931 if (voltage->min_uV == min_uV && voltage->max_uV == max_uV)
2894 goto out; 2932 goto out;
2895 2933
2896 /* If we're trying to set a range that overlaps the current voltage, 2934 /* If we're trying to set a range that overlaps the current voltage,
@@ -2900,8 +2938,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2900 if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) { 2938 if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
2901 current_uV = _regulator_get_voltage(rdev); 2939 current_uV = _regulator_get_voltage(rdev);
2902 if (min_uV <= current_uV && current_uV <= max_uV) { 2940 if (min_uV <= current_uV && current_uV <= max_uV) {
2903 regulator->min_uV = min_uV; 2941 voltage->min_uV = min_uV;
2904 regulator->max_uV = max_uV; 2942 voltage->max_uV = max_uV;
2905 goto out; 2943 goto out;
2906 } 2944 }
2907 } 2945 }
@@ -2919,12 +2957,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2919 goto out; 2957 goto out;
2920 2958
2921 /* restore original values in case of error */ 2959 /* restore original values in case of error */
2922 old_min_uV = regulator->min_uV; 2960 old_min_uV = voltage->min_uV;
2923 old_max_uV = regulator->max_uV; 2961 old_max_uV = voltage->max_uV;
2924 regulator->min_uV = min_uV; 2962 voltage->min_uV = min_uV;
2925 regulator->max_uV = max_uV; 2963 voltage->max_uV = max_uV;
2926 2964
2927 ret = regulator_check_consumers(rdev, &min_uV, &max_uV); 2965 ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state);
2928 if (ret < 0) 2966 if (ret < 0)
2929 goto out2; 2967 goto out2;
2930 2968
@@ -2961,7 +2999,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2961 2999
2962 if (supply_change_uV > 0) { 3000 if (supply_change_uV > 0) {
2963 ret = regulator_set_voltage_unlocked(rdev->supply, 3001 ret = regulator_set_voltage_unlocked(rdev->supply,
2964 best_supply_uV, INT_MAX); 3002 best_supply_uV, INT_MAX, state);
2965 if (ret) { 3003 if (ret) {
2966 dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", 3004 dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
2967 ret); 3005 ret);
@@ -2969,13 +3007,17 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2969 } 3007 }
2970 } 3008 }
2971 3009
2972 ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); 3010 if (state == PM_SUSPEND_ON)
3011 ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
3012 else
3013 ret = _regulator_do_set_suspend_voltage(rdev, min_uV,
3014 max_uV, state);
2973 if (ret < 0) 3015 if (ret < 0)
2974 goto out2; 3016 goto out2;
2975 3017
2976 if (supply_change_uV < 0) { 3018 if (supply_change_uV < 0) {
2977 ret = regulator_set_voltage_unlocked(rdev->supply, 3019 ret = regulator_set_voltage_unlocked(rdev->supply,
2978 best_supply_uV, INT_MAX); 3020 best_supply_uV, INT_MAX, state);
2979 if (ret) 3021 if (ret)
2980 dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", 3022 dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
2981 ret); 3023 ret);
@@ -2986,8 +3028,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2986out: 3028out:
2987 return ret; 3029 return ret;
2988out2: 3030out2:
2989 regulator->min_uV = old_min_uV; 3031 voltage->min_uV = old_min_uV;
2990 regulator->max_uV = old_max_uV; 3032 voltage->max_uV = old_max_uV;
2991 3033
2992 return ret; 3034 return ret;
2993} 3035}
@@ -3016,7 +3058,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
3016 3058
3017 regulator_lock_supply(regulator->rdev); 3059 regulator_lock_supply(regulator->rdev);
3018 3060
3019 ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV); 3061 ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
3062 PM_SUSPEND_ON);
3020 3063
3021 regulator_unlock_supply(regulator->rdev); 3064 regulator_unlock_supply(regulator->rdev);
3022 3065
@@ -3024,6 +3067,89 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
3024} 3067}
3025EXPORT_SYMBOL_GPL(regulator_set_voltage); 3068EXPORT_SYMBOL_GPL(regulator_set_voltage);
3026 3069
3070static inline int regulator_suspend_toggle(struct regulator_dev *rdev,
3071 suspend_state_t state, bool en)
3072{
3073 struct regulator_state *rstate;
3074
3075 rstate = regulator_get_suspend_state(rdev, state);
3076 if (rstate == NULL)
3077 return -EINVAL;
3078
3079 if (!rstate->changeable)
3080 return -EPERM;
3081
3082 rstate->enabled = en;
3083
3084 return 0;
3085}
3086
3087int regulator_suspend_enable(struct regulator_dev *rdev,
3088 suspend_state_t state)
3089{
3090 return regulator_suspend_toggle(rdev, state, true);
3091}
3092EXPORT_SYMBOL_GPL(regulator_suspend_enable);
3093
3094int regulator_suspend_disable(struct regulator_dev *rdev,
3095 suspend_state_t state)
3096{
3097 struct regulator *regulator;
3098 struct regulator_voltage *voltage;
3099
3100 /*
3101 * if any consumer wants this regulator device keeping on in
3102 * suspend states, don't set it as disabled.
3103 */
3104 list_for_each_entry(regulator, &rdev->consumer_list, list) {
3105 voltage = &regulator->voltage[state];
3106 if (voltage->min_uV || voltage->max_uV)
3107 return 0;
3108 }
3109
3110 return regulator_suspend_toggle(rdev, state, false);
3111}
3112EXPORT_SYMBOL_GPL(regulator_suspend_disable);
3113
3114static int _regulator_set_suspend_voltage(struct regulator *regulator,
3115 int min_uV, int max_uV,
3116 suspend_state_t state)
3117{
3118 struct regulator_dev *rdev = regulator->rdev;
3119 struct regulator_state *rstate;
3120
3121 rstate = regulator_get_suspend_state(rdev, state);
3122 if (rstate == NULL)
3123 return -EINVAL;
3124
3125 if (rstate->min_uV == rstate->max_uV) {
3126 rdev_err(rdev, "The suspend voltage can't be changed!\n");
3127 return -EPERM;
3128 }
3129
3130 return regulator_set_voltage_unlocked(regulator, min_uV, max_uV, state);
3131}
3132
3133int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
3134 int max_uV, suspend_state_t state)
3135{
3136 int ret = 0;
3137
3138 /* PM_SUSPEND_ON is handled by regulator_set_voltage() */
3139 if (regulator_check_states(state) || state == PM_SUSPEND_ON)
3140 return -EINVAL;
3141
3142 regulator_lock_supply(regulator->rdev);
3143
3144 ret = _regulator_set_suspend_voltage(regulator, min_uV,
3145 max_uV, state);
3146
3147 regulator_unlock_supply(regulator->rdev);
3148
3149 return ret;
3150}
3151EXPORT_SYMBOL_GPL(regulator_set_suspend_voltage);
3152
3027/** 3153/**
3028 * regulator_set_voltage_time - get raise/fall time 3154 * regulator_set_voltage_time - get raise/fall time
3029 * @regulator: regulator source 3155 * @regulator: regulator source
@@ -3117,6 +3243,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
3117int regulator_sync_voltage(struct regulator *regulator) 3243int regulator_sync_voltage(struct regulator *regulator)
3118{ 3244{
3119 struct regulator_dev *rdev = regulator->rdev; 3245 struct regulator_dev *rdev = regulator->rdev;
3246 struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
3120 int ret, min_uV, max_uV; 3247 int ret, min_uV, max_uV;
3121 3248
3122 mutex_lock(&rdev->mutex); 3249 mutex_lock(&rdev->mutex);
@@ -3128,20 +3255,20 @@ int regulator_sync_voltage(struct regulator *regulator)
3128 } 3255 }
3129 3256
3130 /* This is only going to work if we've had a voltage configured. */ 3257 /* This is only going to work if we've had a voltage configured. */
3131 if (!regulator->min_uV && !regulator->max_uV) { 3258 if (!voltage->min_uV && !voltage->max_uV) {
3132 ret = -EINVAL; 3259 ret = -EINVAL;
3133 goto out; 3260 goto out;
3134 } 3261 }
3135 3262
3136 min_uV = regulator->min_uV; 3263 min_uV = voltage->min_uV;
3137 max_uV = regulator->max_uV; 3264 max_uV = voltage->max_uV;
3138 3265
3139 /* This should be a paranoia check... */ 3266 /* This should be a paranoia check... */
3140 ret = regulator_check_voltage(rdev, &min_uV, &max_uV); 3267 ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
3141 if (ret < 0) 3268 if (ret < 0)
3142 goto out; 3269 goto out;
3143 3270
3144 ret = regulator_check_consumers(rdev, &min_uV, &max_uV); 3271 ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0);
3145 if (ret < 0) 3272 if (ret < 0)
3146 goto out; 3273 goto out;
3147 3274
@@ -3897,12 +4024,6 @@ static void regulator_dev_release(struct device *dev)
3897 kfree(rdev); 4024 kfree(rdev);
3898} 4025}
3899 4026
3900struct class regulator_class = {
3901 .name = "regulator",
3902 .dev_release = regulator_dev_release,
3903 .dev_groups = regulator_dev_groups,
3904};
3905
3906static void rdev_init_debugfs(struct regulator_dev *rdev) 4027static void rdev_init_debugfs(struct regulator_dev *rdev)
3907{ 4028{
3908 struct device *parent = rdev->dev.parent; 4029 struct device *parent = rdev->dev.parent;
@@ -4153,81 +4274,86 @@ void regulator_unregister(struct regulator_dev *rdev)
4153} 4274}
4154EXPORT_SYMBOL_GPL(regulator_unregister); 4275EXPORT_SYMBOL_GPL(regulator_unregister);
4155 4276
4156static int _regulator_suspend_prepare(struct device *dev, void *data) 4277#ifdef CONFIG_SUSPEND
4278static int _regulator_suspend_late(struct device *dev, void *data)
4157{ 4279{
4158 struct regulator_dev *rdev = dev_to_rdev(dev); 4280 struct regulator_dev *rdev = dev_to_rdev(dev);
4159 const suspend_state_t *state = data; 4281 suspend_state_t *state = data;
4160 int ret; 4282 int ret;
4161 4283
4162 mutex_lock(&rdev->mutex); 4284 mutex_lock(&rdev->mutex);
4163 ret = suspend_prepare(rdev, *state); 4285 ret = suspend_set_state(rdev, *state);
4164 mutex_unlock(&rdev->mutex); 4286 mutex_unlock(&rdev->mutex);
4165 4287
4166 return ret; 4288 return ret;
4167} 4289}
4168 4290
4169/** 4291/**
4170 * regulator_suspend_prepare - prepare regulators for system wide suspend 4292 * regulator_suspend_late - prepare regulators for system wide suspend
4171 * @state: system suspend state 4293 * @state: system suspend state
4172 * 4294 *
4173 * Configure each regulator with it's suspend operating parameters for state. 4295 * Configure each regulator with it's suspend operating parameters for state.
4174 * This will usually be called by machine suspend code prior to supending.
4175 */ 4296 */
4176int regulator_suspend_prepare(suspend_state_t state) 4297static int regulator_suspend_late(struct device *dev)
4177{ 4298{
4178 /* ON is handled by regulator active state */ 4299 suspend_state_t state = pm_suspend_target_state;
4179 if (state == PM_SUSPEND_ON)
4180 return -EINVAL;
4181 4300
4182 return class_for_each_device(&regulator_class, NULL, &state, 4301 return class_for_each_device(&regulator_class, NULL, &state,
4183 _regulator_suspend_prepare); 4302 _regulator_suspend_late);
4184} 4303}
4185EXPORT_SYMBOL_GPL(regulator_suspend_prepare); 4304static int _regulator_resume_early(struct device *dev, void *data)
4186
4187static int _regulator_suspend_finish(struct device *dev, void *data)
4188{ 4305{
4306 int ret = 0;
4189 struct regulator_dev *rdev = dev_to_rdev(dev); 4307 struct regulator_dev *rdev = dev_to_rdev(dev);
4190 int ret; 4308 suspend_state_t *state = data;
4309 struct regulator_state *rstate;
4310
4311 rstate = regulator_get_suspend_state(rdev, *state);
4312 if (rstate == NULL)
4313 return -EINVAL;
4191 4314
4192 mutex_lock(&rdev->mutex); 4315 mutex_lock(&rdev->mutex);
4193 if (rdev->use_count > 0 || rdev->constraints->always_on) {
4194 if (!_regulator_is_enabled(rdev)) {
4195 ret = _regulator_do_enable(rdev);
4196 if (ret)
4197 dev_err(dev,
4198 "Failed to resume regulator %d\n",
4199 ret);
4200 }
4201 } else {
4202 if (!have_full_constraints())
4203 goto unlock;
4204 if (!_regulator_is_enabled(rdev))
4205 goto unlock;
4206 4316
4207 ret = _regulator_do_disable(rdev); 4317 if (rdev->desc->ops->resume_early &&
4208 if (ret) 4318 (rstate->enabled == ENABLE_IN_SUSPEND ||
4209 dev_err(dev, "Failed to suspend regulator %d\n", ret); 4319 rstate->enabled == DISABLE_IN_SUSPEND))
4210 } 4320 ret = rdev->desc->ops->resume_early(rdev);
4211unlock: 4321
4212 mutex_unlock(&rdev->mutex); 4322 mutex_unlock(&rdev->mutex);
4213 4323
4214 /* Keep processing regulators in spite of any errors */ 4324 return ret;
4215 return 0;
4216} 4325}
4217 4326
4218/** 4327static int regulator_resume_early(struct device *dev)
4219 * regulator_suspend_finish - resume regulators from system wide suspend
4220 *
4221 * Turn on regulators that might be turned off by regulator_suspend_prepare
4222 * and that should be turned on according to the regulators properties.
4223 */
4224int regulator_suspend_finish(void)
4225{ 4328{
4226 return class_for_each_device(&regulator_class, NULL, NULL, 4329 suspend_state_t state = pm_suspend_target_state;
4227 _regulator_suspend_finish); 4330
4331 return class_for_each_device(&regulator_class, NULL, &state,
4332 _regulator_resume_early);
4228} 4333}
4229EXPORT_SYMBOL_GPL(regulator_suspend_finish);
4230 4334
4335#else /* !CONFIG_SUSPEND */
4336
4337#define regulator_suspend_late NULL
4338#define regulator_resume_early NULL
4339
4340#endif /* !CONFIG_SUSPEND */
4341
4342#ifdef CONFIG_PM
4343static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
4344 .suspend_late = regulator_suspend_late,
4345 .resume_early = regulator_resume_early,
4346};
4347#endif
4348
4349struct class regulator_class = {
4350 .name = "regulator",
4351 .dev_release = regulator_dev_release,
4352 .dev_groups = regulator_dev_groups,
4353#ifdef CONFIG_PM
4354 .pm = &regulator_pm_ops,
4355#endif
4356};
4231/** 4357/**
4232 * regulator_has_full_constraints - the system has fully specified constraints 4358 * regulator_has_full_constraints - the system has fully specified constraints
4233 * 4359 *
@@ -4403,8 +4529,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
4403 switch (rdev->desc->type) { 4529 switch (rdev->desc->type) {
4404 case REGULATOR_VOLTAGE: 4530 case REGULATOR_VOLTAGE:
4405 seq_printf(s, "%37dmV %5dmV", 4531 seq_printf(s, "%37dmV %5dmV",
4406 consumer->min_uV / 1000, 4532 consumer->voltage[PM_SUSPEND_ON].min_uV / 1000,
4407 consumer->max_uV / 1000); 4533 consumer->voltage[PM_SUSPEND_ON].max_uV / 1000);
4408 break; 4534 break;
4409 case REGULATOR_CURRENT: 4535 case REGULATOR_CURRENT:
4410 break; 4536 break;
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
index 2f3218be5b8d..abfd56e8c78a 100644
--- a/drivers/regulator/internal.h
+++ b/drivers/regulator/internal.h
@@ -16,10 +16,25 @@
16#ifndef __REGULATOR_INTERNAL_H 16#ifndef __REGULATOR_INTERNAL_H
17#define __REGULATOR_INTERNAL_H 17#define __REGULATOR_INTERNAL_H
18 18
19#include <linux/suspend.h>
20
21#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1)
22
23struct regulator_voltage {
24 int min_uV;
25 int max_uV;
26};
27
19/* 28/*
20 * struct regulator 29 * struct regulator
21 * 30 *
22 * One for each consumer device. 31 * One for each consumer device.
32 * @voltage - a voltage array for each state of runtime, i.e.:
33 * PM_SUSPEND_ON
34 * PM_SUSPEND_TO_IDLE
35 * PM_SUSPEND_STANDBY
36 * PM_SUSPEND_MEM
37 * PM_SUSPEND_MAX
23 */ 38 */
24struct regulator { 39struct regulator {
25 struct device *dev; 40 struct device *dev;
@@ -27,8 +42,7 @@ struct regulator {
27 unsigned int always_on:1; 42 unsigned int always_on:1;
28 unsigned int bypass:1; 43 unsigned int bypass:1;
29 int uA_load; 44 int uA_load;
30 int min_uV; 45 struct regulator_voltage voltage[REGULATOR_STATES_NUM];
31 int max_uV;
32 const char *supply_name; 46 const char *supply_name;
33 struct device_attribute dev_attr; 47 struct device_attribute dev_attr;
34 struct regulator_dev *rdev; 48 struct regulator_dev *rdev;
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 54e810ae93d6..092ed6efb3ec 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -177,14 +177,30 @@ static void of_get_regulation_constraints(struct device_node *np,
177 177
178 if (of_property_read_bool(suspend_np, 178 if (of_property_read_bool(suspend_np,
179 "regulator-on-in-suspend")) 179 "regulator-on-in-suspend"))
180 suspend_state->enabled = true; 180 suspend_state->enabled = ENABLE_IN_SUSPEND;
181 else if (of_property_read_bool(suspend_np, 181 else if (of_property_read_bool(suspend_np,
182 "regulator-off-in-suspend")) 182 "regulator-off-in-suspend"))
183 suspend_state->disabled = true; 183 suspend_state->enabled = DISABLE_IN_SUSPEND;
184 else
185 suspend_state->enabled = DO_NOTHING_IN_SUSPEND;
186
187 if (!of_property_read_u32(np, "regulator-suspend-min-microvolt",
188 &pval))
189 suspend_state->min_uV = pval;
190
191 if (!of_property_read_u32(np, "regulator-suspend-max-microvolt",
192 &pval))
193 suspend_state->max_uV = pval;
184 194
185 if (!of_property_read_u32(suspend_np, 195 if (!of_property_read_u32(suspend_np,
186 "regulator-suspend-microvolt", &pval)) 196 "regulator-suspend-microvolt", &pval))
187 suspend_state->uV = pval; 197 suspend_state->uV = pval;
198 else /* otherwise use min_uV as default suspend voltage */
199 suspend_state->uV = suspend_state->min_uV;
200
201 if (of_property_read_bool(suspend_np,
202 "regulator-changeable-in-suspend"))
203 suspend_state->changeable = true;
188 204
189 if (i == PM_SUSPEND_MEM) 205 if (i == PM_SUSPEND_MEM)
190 constraints->initial_state = PM_SUSPEND_MEM; 206 constraints->initial_state = PM_SUSPEND_MEM;
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 94417b4226bd..4c00486b7a78 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -214,6 +214,8 @@ struct regulator_ops {
214 /* set regulator suspend operating mode (defined in consumer.h) */ 214 /* set regulator suspend operating mode (defined in consumer.h) */
215 int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode); 215 int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
216 216
217 int (*resume_early)(struct regulator_dev *rdev);
218
217 int (*set_pull_down) (struct regulator_dev *); 219 int (*set_pull_down) (struct regulator_dev *);
218}; 220};
219 221
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 9cd4fef37203..93a04893c739 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -42,6 +42,16 @@ struct regulator;
42#define REGULATOR_CHANGE_DRMS 0x10 42#define REGULATOR_CHANGE_DRMS 0x10
43#define REGULATOR_CHANGE_BYPASS 0x20 43#define REGULATOR_CHANGE_BYPASS 0x20
44 44
45/*
46 * operations in suspend mode
47 * DO_NOTHING_IN_SUSPEND - the default value
48 * DISABLE_IN_SUSPEND - turn off regulator in suspend states
49 * ENABLE_IN_SUSPEND - keep regulator on in suspend states
50 */
51#define DO_NOTHING_IN_SUSPEND (-1)
52#define DISABLE_IN_SUSPEND 0
53#define ENABLE_IN_SUSPEND 1
54
45/* Regulator active discharge flags */ 55/* Regulator active discharge flags */
46enum regulator_active_discharge { 56enum regulator_active_discharge {
47 REGULATOR_ACTIVE_DISCHARGE_DEFAULT, 57 REGULATOR_ACTIVE_DISCHARGE_DEFAULT,
@@ -56,16 +66,24 @@ enum regulator_active_discharge {
56 * state. One of enabled or disabled must be set for the 66 * state. One of enabled or disabled must be set for the
57 * configuration to be applied. 67 * configuration to be applied.
58 * 68 *
59 * @uV: Operating voltage during suspend. 69 * @uV: Default operating voltage during suspend, it can be adjusted
70 * among <min_uV, max_uV>.
71 * @min_uV: Minimum suspend voltage may be set.
72 * @max_uV: Maximum suspend voltage may be set.
60 * @mode: Operating mode during suspend. 73 * @mode: Operating mode during suspend.
61 * @enabled: Enabled during suspend. 74 * @enabled: operations during suspend.
62 * @disabled: Disabled during suspend. 75 * - DO_NOTHING_IN_SUSPEND
76 * - DISABLE_IN_SUSPEND
77 * - ENABLE_IN_SUSPEND
78 * @changeable: Is this state can be switched between enabled/disabled,
63 */ 79 */
64struct regulator_state { 80struct regulator_state {
65 int uV; /* suspend voltage */ 81 int uV;
66 unsigned int mode; /* suspend regulator operating mode */ 82 int min_uV;
67 int enabled; /* is regulator enabled in this suspend state */ 83 int max_uV;
68 int disabled; /* is the regulator disabled in this suspend state */ 84 unsigned int mode;
85 int enabled;
86 bool changeable;
69}; 87};
70 88
71/** 89/**
@@ -225,12 +243,12 @@ struct regulator_init_data {
225 243
226#ifdef CONFIG_REGULATOR 244#ifdef CONFIG_REGULATOR
227void regulator_has_full_constraints(void); 245void regulator_has_full_constraints(void);
228int regulator_suspend_prepare(suspend_state_t state);
229int regulator_suspend_finish(void);
230#else 246#else
231static inline void regulator_has_full_constraints(void) 247static inline void regulator_has_full_constraints(void)
232{ 248{
233} 249}
250#endif
251
234static inline int regulator_suspend_prepare(suspend_state_t state) 252static inline int regulator_suspend_prepare(suspend_state_t state)
235{ 253{
236 return 0; 254 return 0;
@@ -239,6 +257,5 @@ static inline int regulator_suspend_finish(void)
239{ 257{
240 return 0; 258 return 0;
241} 259}
242#endif
243 260
244#endif 261#endif