aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunyan Zhang <zhang.chunyan@linaro.org>2018-01-26 08:08:44 -0500
committerMark Brown <broonie@kernel.org>2018-01-26 09:43:45 -0500
commitc360a6df02cdba47c0590ffc7d15ec6687183e8c (patch)
treefcf591be1d9ec3afd439e8e7d397309649cbf6f6
parent057c76440c791eb31eb68f3b003f67d00fcce51a (diff)
regulator: make regulator voltage be an array to support more states
Some regulator consumers would like to make the regulator device keeping a voltage range output when the system entering into suspend states. Making regulator voltage be an array can allow consumers to set voltage for normal state as well as for suspend states through the same code. Signed-off-by: Chunyan Zhang <zhang.chunyan@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/core.c63
-rw-r--r--drivers/regulator/internal.h18
2 files changed, 51 insertions, 30 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index b64b7916507f..97bc9f7adf2f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -240,22 +240,25 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
240 * regulator consumers 240 * regulator consumers
241 */ 241 */
242static int regulator_check_consumers(struct regulator_dev *rdev, 242static int regulator_check_consumers(struct regulator_dev *rdev,
243 int *min_uV, int *max_uV) 243 int *min_uV, int *max_uV,
244 suspend_state_t state)
244{ 245{
245 struct regulator *regulator; 246 struct regulator *regulator;
247 struct regulator_voltage *voltage;
246 248
247 list_for_each_entry(regulator, &rdev->consumer_list, list) { 249 list_for_each_entry(regulator, &rdev->consumer_list, list) {
250 voltage = &regulator->voltage[state];
248 /* 251 /*
249 * Assume consumers that didn't say anything are OK 252 * Assume consumers that didn't say anything are OK
250 * with anything in the constraint range. 253 * with anything in the constraint range.
251 */ 254 */
252 if (!regulator->min_uV && !regulator->max_uV) 255 if (!voltage->min_uV && !voltage->max_uV)
253 continue; 256 continue;
254 257
255 if (*max_uV > regulator->max_uV) 258 if (*max_uV > voltage->max_uV)
256 *max_uV = regulator->max_uV; 259 *max_uV = voltage->max_uV;
257 if (*min_uV < regulator->min_uV) 260 if (*min_uV < voltage->min_uV)
258 *min_uV = regulator->min_uV; 261 *min_uV = voltage->min_uV;
259 } 262 }
260 263
261 if (*min_uV > *max_uV) { 264 if (*min_uV > *max_uV) {
@@ -1356,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
1356 debugfs_create_u32("uA_load", 0444, regulator->debugfs, 1359 debugfs_create_u32("uA_load", 0444, regulator->debugfs,
1357 &regulator->uA_load); 1360 &regulator->uA_load);
1358 debugfs_create_u32("min_uV", 0444, regulator->debugfs, 1361 debugfs_create_u32("min_uV", 0444, regulator->debugfs,
1359 &regulator->min_uV); 1362 &regulator->voltage[PM_SUSPEND_ON].min_uV);
1360 debugfs_create_u32("max_uV", 0444, regulator->debugfs, 1363 debugfs_create_u32("max_uV", 0444, regulator->debugfs,
1361 &regulator->max_uV); 1364 &regulator->voltage[PM_SUSPEND_ON].max_uV);
1362 debugfs_create_file("constraint_flags", 0444, 1365 debugfs_create_file("constraint_flags", 0444,
1363 regulator->debugfs, regulator, 1366 regulator->debugfs, regulator,
1364 &constraint_flags_fops); 1367 &constraint_flags_fops);
@@ -2898,9 +2901,11 @@ out:
2898} 2901}
2899 2902
2900static int regulator_set_voltage_unlocked(struct regulator *regulator, 2903static int regulator_set_voltage_unlocked(struct regulator *regulator,
2901 int min_uV, int max_uV) 2904 int min_uV, int max_uV,
2905 suspend_state_t state)
2902{ 2906{
2903 struct regulator_dev *rdev = regulator->rdev; 2907 struct regulator_dev *rdev = regulator->rdev;
2908 struct regulator_voltage *voltage = &regulator->voltage[state];
2904 int ret = 0; 2909 int ret = 0;
2905 int old_min_uV, old_max_uV; 2910 int old_min_uV, old_max_uV;
2906 int current_uV; 2911 int current_uV;
@@ -2911,7 +2916,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2911 * should be a noop (some cpufreq implementations use the same 2916 * should be a noop (some cpufreq implementations use the same
2912 * voltage for multiple frequencies, for example). 2917 * voltage for multiple frequencies, for example).
2913 */ 2918 */
2914 if (regulator->min_uV == min_uV && regulator->max_uV == max_uV) 2919 if (voltage->min_uV == min_uV && voltage->max_uV == max_uV)
2915 goto out; 2920 goto out;
2916 2921
2917 /* If we're trying to set a range that overlaps the current voltage, 2922 /* If we're trying to set a range that overlaps the current voltage,
@@ -2921,8 +2926,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2921 if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) { 2926 if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
2922 current_uV = _regulator_get_voltage(rdev); 2927 current_uV = _regulator_get_voltage(rdev);
2923 if (min_uV <= current_uV && current_uV <= max_uV) { 2928 if (min_uV <= current_uV && current_uV <= max_uV) {
2924 regulator->min_uV = min_uV; 2929 voltage->min_uV = min_uV;
2925 regulator->max_uV = max_uV; 2930 voltage->max_uV = max_uV;
2926 goto out; 2931 goto out;
2927 } 2932 }
2928 } 2933 }
@@ -2940,12 +2945,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2940 goto out; 2945 goto out;
2941 2946
2942 /* restore original values in case of error */ 2947 /* restore original values in case of error */
2943 old_min_uV = regulator->min_uV; 2948 old_min_uV = voltage->min_uV;
2944 old_max_uV = regulator->max_uV; 2949 old_max_uV = voltage->max_uV;
2945 regulator->min_uV = min_uV; 2950 voltage->min_uV = min_uV;
2946 regulator->max_uV = max_uV; 2951 voltage->max_uV = max_uV;
2947 2952
2948 ret = regulator_check_consumers(rdev, &min_uV, &max_uV); 2953 ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state);
2949 if (ret < 0) 2954 if (ret < 0)
2950 goto out2; 2955 goto out2;
2951 2956
@@ -2982,7 +2987,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2982 2987
2983 if (supply_change_uV > 0) { 2988 if (supply_change_uV > 0) {
2984 ret = regulator_set_voltage_unlocked(rdev->supply, 2989 ret = regulator_set_voltage_unlocked(rdev->supply,
2985 best_supply_uV, INT_MAX); 2990 best_supply_uV, INT_MAX, state);
2986 if (ret) { 2991 if (ret) {
2987 dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", 2992 dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
2988 ret); 2993 ret);
@@ -2996,7 +3001,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
2996 3001
2997 if (supply_change_uV < 0) { 3002 if (supply_change_uV < 0) {
2998 ret = regulator_set_voltage_unlocked(rdev->supply, 3003 ret = regulator_set_voltage_unlocked(rdev->supply,
2999 best_supply_uV, INT_MAX); 3004 best_supply_uV, INT_MAX, state);
3000 if (ret) 3005 if (ret)
3001 dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", 3006 dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
3002 ret); 3007 ret);
@@ -3007,8 +3012,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3007out: 3012out:
3008 return ret; 3013 return ret;
3009out2: 3014out2:
3010 regulator->min_uV = old_min_uV; 3015 voltage->min_uV = old_min_uV;
3011 regulator->max_uV = old_max_uV; 3016 voltage->max_uV = old_max_uV;
3012 3017
3013 return ret; 3018 return ret;
3014} 3019}
@@ -3037,7 +3042,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
3037 3042
3038 regulator_lock_supply(regulator->rdev); 3043 regulator_lock_supply(regulator->rdev);
3039 3044
3040 ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV); 3045 ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
3046 PM_SUSPEND_ON);
3041 3047
3042 regulator_unlock_supply(regulator->rdev); 3048 regulator_unlock_supply(regulator->rdev);
3043 3049
@@ -3138,6 +3144,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
3138int regulator_sync_voltage(struct regulator *regulator) 3144int regulator_sync_voltage(struct regulator *regulator)
3139{ 3145{
3140 struct regulator_dev *rdev = regulator->rdev; 3146 struct regulator_dev *rdev = regulator->rdev;
3147 struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
3141 int ret, min_uV, max_uV; 3148 int ret, min_uV, max_uV;
3142 3149
3143 mutex_lock(&rdev->mutex); 3150 mutex_lock(&rdev->mutex);
@@ -3149,20 +3156,20 @@ int regulator_sync_voltage(struct regulator *regulator)
3149 } 3156 }
3150 3157
3151 /* This is only going to work if we've had a voltage configured. */ 3158 /* This is only going to work if we've had a voltage configured. */
3152 if (!regulator->min_uV && !regulator->max_uV) { 3159 if (!voltage->min_uV && !voltage->max_uV) {
3153 ret = -EINVAL; 3160 ret = -EINVAL;
3154 goto out; 3161 goto out;
3155 } 3162 }
3156 3163
3157 min_uV = regulator->min_uV; 3164 min_uV = voltage->min_uV;
3158 max_uV = regulator->max_uV; 3165 max_uV = voltage->max_uV;
3159 3166
3160 /* This should be a paranoia check... */ 3167 /* This should be a paranoia check... */
3161 ret = regulator_check_voltage(rdev, &min_uV, &max_uV); 3168 ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
3162 if (ret < 0) 3169 if (ret < 0)
3163 goto out; 3170 goto out;
3164 3171
3165 ret = regulator_check_consumers(rdev, &min_uV, &max_uV); 3172 ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0);
3166 if (ret < 0) 3173 if (ret < 0)
3167 goto out; 3174 goto out;
3168 3175
@@ -4424,8 +4431,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
4424 switch (rdev->desc->type) { 4431 switch (rdev->desc->type) {
4425 case REGULATOR_VOLTAGE: 4432 case REGULATOR_VOLTAGE:
4426 seq_printf(s, "%37dmV %5dmV", 4433 seq_printf(s, "%37dmV %5dmV",
4427 consumer->min_uV / 1000, 4434 consumer->voltage[PM_SUSPEND_ON].min_uV / 1000,
4428 consumer->max_uV / 1000); 4435 consumer->voltage[PM_SUSPEND_ON].max_uV / 1000);
4429 break; 4436 break;
4430 case REGULATOR_CURRENT: 4437 case REGULATOR_CURRENT:
4431 break; 4438 break;
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
index 66a8ea0c8386..aba8e4149838 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;