Skip to content

Commit c360a6d

Browse files
Chunyan Zhangbroonie
authored andcommitted
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>
1 parent 057c764 commit c360a6d

File tree

2 files changed

+51
-30
lines changed

2 files changed

+51
-30
lines changed

drivers/regulator/core.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,25 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
240240
* regulator consumers
241241
*/
242242
static 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)
244245
{
245246
struct regulator *regulator;
247+
struct regulator_voltage *voltage;
246248

247249
list_for_each_entry(regulator, &rdev->consumer_list, list) {
250+
voltage = &regulator->voltage[state];
248251
/*
249252
* Assume consumers that didn't say anything are OK
250253
* with anything in the constraint range.
251254
*/
252-
if (!regulator->min_uV && !regulator->max_uV)
255+
if (!voltage->min_uV && !voltage->max_uV)
253256
continue;
254257

255-
if (*max_uV > regulator->max_uV)
256-
*max_uV = regulator->max_uV;
257-
if (*min_uV < regulator->min_uV)
258-
*min_uV = regulator->min_uV;
258+
if (*max_uV > voltage->max_uV)
259+
*max_uV = voltage->max_uV;
260+
if (*min_uV < voltage->min_uV)
261+
*min_uV = voltage->min_uV;
259262
}
260263

261264
if (*min_uV > *max_uV) {
@@ -1356,9 +1359,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
13561359
debugfs_create_u32("uA_load", 0444, regulator->debugfs,
13571360
&regulator->uA_load);
13581361
debugfs_create_u32("min_uV", 0444, regulator->debugfs,
1359-
&regulator->min_uV);
1362+
&regulator->voltage[PM_SUSPEND_ON].min_uV);
13601363
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
1361-
&regulator->max_uV);
1364+
&regulator->voltage[PM_SUSPEND_ON].max_uV);
13621365
debugfs_create_file("constraint_flags", 0444,
13631366
regulator->debugfs, regulator,
13641367
&constraint_flags_fops);
@@ -2898,9 +2901,11 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
28982901
}
28992902

29002903
static 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)
29022906
{
29032907
struct regulator_dev *rdev = regulator->rdev;
2908+
struct regulator_voltage *voltage = &regulator->voltage[state];
29042909
int ret = 0;
29052910
int old_min_uV, old_max_uV;
29062911
int current_uV;
@@ -2911,7 +2916,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
29112916
* should be a noop (some cpufreq implementations use the same
29122917
* voltage for multiple frequencies, for example).
29132918
*/
2914-
if (regulator->min_uV == min_uV && regulator->max_uV == max_uV)
2919+
if (voltage->min_uV == min_uV && voltage->max_uV == max_uV)
29152920
goto out;
29162921

29172922
/* 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,
29212926
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
29222927
current_uV = _regulator_get_voltage(rdev);
29232928
if (min_uV <= current_uV && current_uV <= max_uV) {
2924-
regulator->min_uV = min_uV;
2925-
regulator->max_uV = max_uV;
2929+
voltage->min_uV = min_uV;
2930+
voltage->max_uV = max_uV;
29262931
goto out;
29272932
}
29282933
}
@@ -2940,12 +2945,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
29402945
goto out;
29412946

29422947
/* restore original values in case of error */
2943-
old_min_uV = regulator->min_uV;
2944-
old_max_uV = regulator->max_uV;
2945-
regulator->min_uV = min_uV;
2946-
regulator->max_uV = max_uV;
2948+
old_min_uV = voltage->min_uV;
2949+
old_max_uV = voltage->max_uV;
2950+
voltage->min_uV = min_uV;
2951+
voltage->max_uV = max_uV;
29472952

2948-
ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
2953+
ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state);
29492954
if (ret < 0)
29502955
goto out2;
29512956

@@ -2982,7 +2987,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
29822987

29832988
if (supply_change_uV > 0) {
29842989
ret = regulator_set_voltage_unlocked(rdev->supply,
2985-
best_supply_uV, INT_MAX);
2990+
best_supply_uV, INT_MAX, state);
29862991
if (ret) {
29872992
dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
29882993
ret);
@@ -2996,7 +3001,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
29963001

29973002
if (supply_change_uV < 0) {
29983003
ret = regulator_set_voltage_unlocked(rdev->supply,
2999-
best_supply_uV, INT_MAX);
3004+
best_supply_uV, INT_MAX, state);
30003005
if (ret)
30013006
dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
30023007
ret);
@@ -3007,8 +3012,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
30073012
out:
30083013
return ret;
30093014
out2:
3010-
regulator->min_uV = old_min_uV;
3011-
regulator->max_uV = old_max_uV;
3015+
voltage->min_uV = old_min_uV;
3016+
voltage->max_uV = old_max_uV;
30123017

30133018
return ret;
30143019
}
@@ -3037,7 +3042,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
30373042

30383043
regulator_lock_supply(regulator->rdev);
30393044

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);
30413047

30423048
regulator_unlock_supply(regulator->rdev);
30433049

@@ -3138,6 +3144,7 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage_time_sel);
31383144
int regulator_sync_voltage(struct regulator *regulator)
31393145
{
31403146
struct regulator_dev *rdev = regulator->rdev;
3147+
struct regulator_voltage *voltage = &regulator->voltage[PM_SUSPEND_ON];
31413148
int ret, min_uV, max_uV;
31423149

31433150
mutex_lock(&rdev->mutex);
@@ -3149,20 +3156,20 @@ int regulator_sync_voltage(struct regulator *regulator)
31493156
}
31503157

31513158
/* 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) {
31533160
ret = -EINVAL;
31543161
goto out;
31553162
}
31563163

3157-
min_uV = regulator->min_uV;
3158-
max_uV = regulator->max_uV;
3164+
min_uV = voltage->min_uV;
3165+
max_uV = voltage->max_uV;
31593166

31603167
/* This should be a paranoia check... */
31613168
ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
31623169
if (ret < 0)
31633170
goto out;
31643171

3165-
ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
3172+
ret = regulator_check_consumers(rdev, &min_uV, &max_uV, 0);
31663173
if (ret < 0)
31673174
goto out;
31683175

@@ -4424,8 +4431,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,
44244431
switch (rdev->desc->type) {
44254432
case REGULATOR_VOLTAGE:
44264433
seq_printf(s, "%37dmV %5dmV",
4427-
consumer->min_uV / 1000,
4428-
consumer->max_uV / 1000);
4434+
consumer->voltage[PM_SUSPEND_ON].min_uV / 1000,
4435+
consumer->voltage[PM_SUSPEND_ON].max_uV / 1000);
44294436
break;
44304437
case REGULATOR_CURRENT:
44314438
break;

drivers/regulator/internal.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,33 @@
1616
#ifndef __REGULATOR_INTERNAL_H
1717
#define __REGULATOR_INTERNAL_H
1818

19+
#include <linux/suspend.h>
20+
21+
#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1)
22+
23+
struct regulator_voltage {
24+
int min_uV;
25+
int max_uV;
26+
};
27+
1928
/*
2029
* struct regulator
2130
*
2231
* 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
2338
*/
2439
struct regulator {
2540
struct device *dev;
2641
struct list_head list;
2742
unsigned int always_on:1;
2843
unsigned int bypass:1;
2944
int uA_load;
30-
int min_uV;
31-
int max_uV;
45+
struct regulator_voltage voltage[REGULATOR_STATES_NUM];
3246
const char *supply_name;
3347
struct device_attribute dev_attr;
3448
struct regulator_dev *rdev;

0 commit comments

Comments
 (0)