diff options
author | Maciej Purski <m.purski@samsung.com> | 2018-04-23 10:33:42 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-05-17 03:05:51 -0400 |
commit | 456e7cdf3b1a14e2606b8b687385ab2e3f23a49a (patch) | |
tree | 4e2dd59031c7112142205dc0c116019872c1be10 | |
parent | 696861761a58d8c93605b5663824929fb6540f16 (diff) |
regulator: core: Change voltage setting path
On Odroid XU3/4 and other Exynos5422 based boards there is a case, that
different devices on the board are supplied by different regulators
with non-fixed voltages. If one of these devices temporarily requires
higher voltage, there might occur a situation that the spread between
two devices' voltages is so high, that there is a risk of changing
'high' and 'low' states on the interconnection between devices powered
by those regulators.
Uncoupled regulators should be a special case of coupled regulators, so
they should share a common voltage setting path. When enabling,
disabling or setting voltage of a coupled regulator, all coupled
regulators should be locked. Regulator's supplies should be locked, when
setting voltage of a single regulator. Enabling a coupled regulator or
setting its voltage should not be possible if some of its coupled
regulators, has not been registered.
Add function for locking coupled regulators and supplies. Extract
a new function regulator_set_voltage_rdev() from
regulator_set_voltage_unlocked(), which is called when setting
voltage of a single regulator.
Signed-off-by: Maciej Purski <m.purski@samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/regulator/core.c | 159 |
1 files changed, 107 insertions, 52 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 225eaca24921..ac97e21bff10 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -107,6 +107,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
107 | int min_uV, int max_uV); | 107 | int min_uV, int max_uV); |
108 | static int regulator_balance_voltage(struct regulator_dev *rdev, | 108 | static int regulator_balance_voltage(struct regulator_dev *rdev, |
109 | suspend_state_t state); | 109 | suspend_state_t state); |
110 | static int regulator_set_voltage_rdev(struct regulator_dev *rdev, | ||
111 | int min_uV, int max_uV, | ||
112 | suspend_state_t state); | ||
110 | static struct regulator *create_regulator(struct regulator_dev *rdev, | 113 | static struct regulator *create_regulator(struct regulator_dev *rdev, |
111 | struct device *dev, | 114 | struct device *dev, |
112 | const char *supply_name); | 115 | const char *supply_name); |
@@ -198,38 +201,67 @@ static void regulator_unlock(struct regulator_dev *rdev) | |||
198 | } | 201 | } |
199 | } | 202 | } |
200 | 203 | ||
201 | /** | 204 | static int regulator_lock_recursive(struct regulator_dev *rdev, |
202 | * regulator_lock_supply - lock a regulator and its supplies | 205 | unsigned int subclass) |
203 | * @rdev: regulator source | ||
204 | */ | ||
205 | static void regulator_lock_supply(struct regulator_dev *rdev) | ||
206 | { | 206 | { |
207 | struct regulator_dev *c_rdev; | ||
207 | int i; | 208 | int i; |
208 | 209 | ||
209 | for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++) | 210 | for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { |
210 | regulator_lock_nested(rdev, i); | 211 | c_rdev = rdev->coupling_desc.coupled_rdevs[i]; |
212 | |||
213 | if (!c_rdev) | ||
214 | continue; | ||
215 | |||
216 | regulator_lock_nested(c_rdev, subclass++); | ||
217 | |||
218 | if (c_rdev->supply) | ||
219 | subclass = | ||
220 | regulator_lock_recursive(c_rdev->supply->rdev, | ||
221 | subclass); | ||
222 | } | ||
223 | |||
224 | return subclass; | ||
211 | } | 225 | } |
212 | 226 | ||
213 | /** | 227 | /** |
214 | * regulator_unlock_supply - unlock a regulator and its supplies | 228 | * regulator_unlock_dependent - unlock regulator's suppliers and coupled |
215 | * @rdev: regulator source | 229 | * regulators |
230 | * @rdev: regulator source | ||
231 | * | ||
232 | * Unlock all regulators related with rdev by coupling or suppling. | ||
216 | */ | 233 | */ |
217 | static void regulator_unlock_supply(struct regulator_dev *rdev) | 234 | static void regulator_unlock_dependent(struct regulator_dev *rdev) |
218 | { | 235 | { |
219 | struct regulator *supply; | 236 | struct regulator_dev *c_rdev; |
237 | int i; | ||
220 | 238 | ||
221 | while (1) { | 239 | for (i = 0; i < rdev->coupling_desc.n_coupled; i++) { |
222 | regulator_unlock(rdev); | 240 | c_rdev = rdev->coupling_desc.coupled_rdevs[i]; |
223 | supply = rdev->supply; | ||
224 | 241 | ||
225 | if (!rdev->supply) | 242 | if (!c_rdev) |
226 | return; | 243 | continue; |
244 | |||
245 | regulator_unlock(c_rdev); | ||
227 | 246 | ||
228 | rdev = supply->rdev; | 247 | if (c_rdev->supply) |
248 | regulator_unlock_dependent(c_rdev->supply->rdev); | ||
229 | } | 249 | } |
230 | } | 250 | } |
231 | 251 | ||
232 | /** | 252 | /** |
253 | * regulator_lock_dependent - lock regulator's suppliers and coupled regulators | ||
254 | * @rdev: regulator source | ||
255 | * | ||
256 | * This function as a wrapper on regulator_lock_recursive(), which locks | ||
257 | * all regulators related with rdev by coupling or suppling. | ||
258 | */ | ||
259 | static inline void regulator_lock_dependent(struct regulator_dev *rdev) | ||
260 | { | ||
261 | regulator_lock_recursive(rdev, 0); | ||
262 | } | ||
263 | |||
264 | /** | ||
233 | * of_get_regulator - get a regulator device node based on supply name | 265 | * of_get_regulator - get a regulator device node based on supply name |
234 | * @dev: Device pointer for the consumer (of regulator) device | 266 | * @dev: Device pointer for the consumer (of regulator) device |
235 | * @supply: regulator supply name | 267 | * @supply: regulator supply name |
@@ -2261,6 +2293,11 @@ int regulator_enable(struct regulator *regulator) | |||
2261 | struct regulator_dev *rdev = regulator->rdev; | 2293 | struct regulator_dev *rdev = regulator->rdev; |
2262 | int ret = 0; | 2294 | int ret = 0; |
2263 | 2295 | ||
2296 | if (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled) { | ||
2297 | rdev_err(rdev, "not all coupled regulators registered\n"); | ||
2298 | return -EPERM; | ||
2299 | } | ||
2300 | |||
2264 | if (regulator->always_on) | 2301 | if (regulator->always_on) |
2265 | return 0; | 2302 | return 0; |
2266 | 2303 | ||
@@ -2270,9 +2307,12 @@ int regulator_enable(struct regulator *regulator) | |||
2270 | return ret; | 2307 | return ret; |
2271 | } | 2308 | } |
2272 | 2309 | ||
2273 | mutex_lock(&rdev->mutex); | 2310 | regulator_lock_dependent(rdev); |
2274 | ret = _regulator_enable(rdev); | 2311 | ret = _regulator_enable(rdev); |
2275 | mutex_unlock(&rdev->mutex); | 2312 | /* balance only if there are regulators coupled */ |
2313 | if (rdev->coupling_desc.n_coupled > 1) | ||
2314 | regulator_balance_voltage(rdev, PM_SUSPEND_ON); | ||
2315 | regulator_unlock_dependent(rdev); | ||
2276 | 2316 | ||
2277 | if (ret != 0 && rdev->supply) | 2317 | if (ret != 0 && rdev->supply) |
2278 | regulator_disable(rdev->supply); | 2318 | regulator_disable(rdev->supply); |
@@ -2378,9 +2418,11 @@ int regulator_disable(struct regulator *regulator) | |||
2378 | if (regulator->always_on) | 2418 | if (regulator->always_on) |
2379 | return 0; | 2419 | return 0; |
2380 | 2420 | ||
2381 | mutex_lock(&rdev->mutex); | 2421 | regulator_lock_dependent(rdev); |
2382 | ret = _regulator_disable(rdev); | 2422 | ret = _regulator_disable(rdev); |
2383 | mutex_unlock(&rdev->mutex); | 2423 | if (rdev->coupling_desc.n_coupled > 1) |
2424 | regulator_balance_voltage(rdev, PM_SUSPEND_ON); | ||
2425 | regulator_unlock_dependent(rdev); | ||
2384 | 2426 | ||
2385 | if (ret == 0 && rdev->supply) | 2427 | if (ret == 0 && rdev->supply) |
2386 | regulator_disable(rdev->supply); | 2428 | regulator_disable(rdev->supply); |
@@ -2429,10 +2471,12 @@ int regulator_force_disable(struct regulator *regulator) | |||
2429 | struct regulator_dev *rdev = regulator->rdev; | 2471 | struct regulator_dev *rdev = regulator->rdev; |
2430 | int ret; | 2472 | int ret; |
2431 | 2473 | ||
2432 | mutex_lock(&rdev->mutex); | 2474 | regulator_lock_dependent(rdev); |
2433 | regulator->uA_load = 0; | 2475 | regulator->uA_load = 0; |
2434 | ret = _regulator_force_disable(regulator->rdev); | 2476 | ret = _regulator_force_disable(regulator->rdev); |
2435 | mutex_unlock(&rdev->mutex); | 2477 | if (rdev->coupling_desc.n_coupled > 1) |
2478 | regulator_balance_voltage(rdev, PM_SUSPEND_ON); | ||
2479 | regulator_unlock_dependent(rdev); | ||
2436 | 2480 | ||
2437 | if (rdev->supply) | 2481 | if (rdev->supply) |
2438 | while (rdev->open_count--) | 2482 | while (rdev->open_count--) |
@@ -2580,9 +2624,9 @@ int regulator_is_enabled(struct regulator *regulator) | |||
2580 | if (regulator->always_on) | 2624 | if (regulator->always_on) |
2581 | return 1; | 2625 | return 1; |
2582 | 2626 | ||
2583 | mutex_lock(®ulator->rdev->mutex); | 2627 | regulator_lock_dependent(regulator->rdev); |
2584 | ret = _regulator_is_enabled(regulator->rdev); | 2628 | ret = _regulator_is_enabled(regulator->rdev); |
2585 | mutex_unlock(®ulator->rdev->mutex); | 2629 | regulator_unlock_dependent(regulator->rdev); |
2586 | 2630 | ||
2587 | return ret; | 2631 | return ret; |
2588 | } | 2632 | } |
@@ -2991,8 +3035,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
2991 | int ret = 0; | 3035 | int ret = 0; |
2992 | int old_min_uV, old_max_uV; | 3036 | int old_min_uV, old_max_uV; |
2993 | int current_uV; | 3037 | int current_uV; |
2994 | int best_supply_uV = 0; | 3038 | |
2995 | int supply_change_uV = 0; | 3039 | if (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled) { |
3040 | rdev_err(rdev, "not all coupled regulators registered\n"); | ||
3041 | ret = -EPERM; | ||
3042 | goto out; | ||
3043 | } | ||
2996 | 3044 | ||
2997 | /* If we're setting the same range as last time the change | 3045 | /* If we're setting the same range as last time the change |
2998 | * should be a noop (some cpufreq implementations use the same | 3046 | * should be a noop (some cpufreq implementations use the same |
@@ -3036,6 +3084,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3036 | if (ret < 0) | 3084 | if (ret < 0) |
3037 | goto out2; | 3085 | goto out2; |
3038 | 3086 | ||
3087 | /* for not coupled regulators this will just set the voltage */ | ||
3088 | ret = regulator_balance_voltage(rdev, state); | ||
3089 | if (ret < 0) | ||
3090 | goto out2; | ||
3091 | |||
3092 | out: | ||
3093 | return 0; | ||
3094 | out2: | ||
3095 | voltage->min_uV = old_min_uV; | ||
3096 | voltage->max_uV = old_max_uV; | ||
3097 | |||
3098 | return ret; | ||
3099 | } | ||
3100 | |||
3101 | static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV, | ||
3102 | int max_uV, suspend_state_t state) | ||
3103 | { | ||
3104 | int best_supply_uV = 0; | ||
3105 | int supply_change_uV = 0; | ||
3106 | int ret; | ||
3107 | |||
3039 | if (rdev->supply && | 3108 | if (rdev->supply && |
3040 | regulator_ops_is_valid(rdev->supply->rdev, | 3109 | regulator_ops_is_valid(rdev->supply->rdev, |
3041 | REGULATOR_CHANGE_VOLTAGE) && | 3110 | REGULATOR_CHANGE_VOLTAGE) && |
@@ -3047,13 +3116,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3047 | selector = regulator_map_voltage(rdev, min_uV, max_uV); | 3116 | selector = regulator_map_voltage(rdev, min_uV, max_uV); |
3048 | if (selector < 0) { | 3117 | if (selector < 0) { |
3049 | ret = selector; | 3118 | ret = selector; |
3050 | goto out2; | 3119 | goto out; |
3051 | } | 3120 | } |
3052 | 3121 | ||
3053 | best_supply_uV = _regulator_list_voltage(rdev, selector, 0); | 3122 | best_supply_uV = _regulator_list_voltage(rdev, selector, 0); |
3054 | if (best_supply_uV < 0) { | 3123 | if (best_supply_uV < 0) { |
3055 | ret = best_supply_uV; | 3124 | ret = best_supply_uV; |
3056 | goto out2; | 3125 | goto out; |
3057 | } | 3126 | } |
3058 | 3127 | ||
3059 | best_supply_uV += rdev->desc->min_dropout_uV; | 3128 | best_supply_uV += rdev->desc->min_dropout_uV; |
@@ -3061,7 +3130,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3061 | current_supply_uV = _regulator_get_voltage(rdev->supply->rdev); | 3130 | current_supply_uV = _regulator_get_voltage(rdev->supply->rdev); |
3062 | if (current_supply_uV < 0) { | 3131 | if (current_supply_uV < 0) { |
3063 | ret = current_supply_uV; | 3132 | ret = current_supply_uV; |
3064 | goto out2; | 3133 | goto out; |
3065 | } | 3134 | } |
3066 | 3135 | ||
3067 | supply_change_uV = best_supply_uV - current_supply_uV; | 3136 | supply_change_uV = best_supply_uV - current_supply_uV; |
@@ -3073,7 +3142,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3073 | if (ret) { | 3142 | if (ret) { |
3074 | dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", | 3143 | dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", |
3075 | ret); | 3144 | ret); |
3076 | goto out2; | 3145 | goto out; |
3077 | } | 3146 | } |
3078 | } | 3147 | } |
3079 | 3148 | ||
@@ -3083,7 +3152,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3083 | ret = _regulator_do_set_suspend_voltage(rdev, min_uV, | 3152 | ret = _regulator_do_set_suspend_voltage(rdev, min_uV, |
3084 | max_uV, state); | 3153 | max_uV, state); |
3085 | if (ret < 0) | 3154 | if (ret < 0) |
3086 | goto out2; | 3155 | goto out; |
3087 | 3156 | ||
3088 | if (supply_change_uV < 0) { | 3157 | if (supply_change_uV < 0) { |
3089 | ret = regulator_set_voltage_unlocked(rdev->supply, | 3158 | ret = regulator_set_voltage_unlocked(rdev->supply, |
@@ -3097,11 +3166,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, | |||
3097 | 3166 | ||
3098 | out: | 3167 | out: |
3099 | return ret; | 3168 | return ret; |
3100 | out2: | ||
3101 | voltage->min_uV = old_min_uV; | ||
3102 | voltage->max_uV = old_max_uV; | ||
3103 | |||
3104 | return ret; | ||
3105 | } | 3169 | } |
3106 | 3170 | ||
3107 | static int regulator_get_optimal_voltage(struct regulator_dev *rdev) | 3171 | static int regulator_get_optimal_voltage(struct regulator_dev *rdev) |
@@ -3274,17 +3338,8 @@ static int regulator_balance_voltage(struct regulator_dev *rdev, | |||
3274 | goto out; | 3338 | goto out; |
3275 | } | 3339 | } |
3276 | 3340 | ||
3277 | /* | ||
3278 | * Lock just the supply regulators, as the regulator itself | ||
3279 | * is already locked by regulator_lock_coupled(). | ||
3280 | */ | ||
3281 | if (best_rdev->supply) | ||
3282 | regulator_lock_supply(best_rdev->supply->rdev); | ||
3283 | |||
3284 | ret = regulator_set_voltage_rdev(best_rdev, best_uV, | 3341 | ret = regulator_set_voltage_rdev(best_rdev, best_uV, |
3285 | best_uV, state); | 3342 | best_uV, state); |
3286 | if (best_rdev->supply) | ||
3287 | regulator_unlock_supply(best_rdev->supply->rdev); | ||
3288 | 3343 | ||
3289 | if (ret < 0) | 3344 | if (ret < 0) |
3290 | goto out; | 3345 | goto out; |
@@ -3316,12 +3371,12 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
3316 | { | 3371 | { |
3317 | int ret = 0; | 3372 | int ret = 0; |
3318 | 3373 | ||
3319 | regulator_lock_supply(regulator->rdev); | 3374 | regulator_lock_dependent(regulator->rdev); |
3320 | 3375 | ||
3321 | ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, | 3376 | ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV, |
3322 | PM_SUSPEND_ON); | 3377 | PM_SUSPEND_ON); |
3323 | 3378 | ||
3324 | regulator_unlock_supply(regulator->rdev); | 3379 | regulator_unlock_dependent(regulator->rdev); |
3325 | 3380 | ||
3326 | return ret; | 3381 | return ret; |
3327 | } | 3382 | } |
@@ -3399,12 +3454,12 @@ int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV, | |||
3399 | if (regulator_check_states(state) || state == PM_SUSPEND_ON) | 3454 | if (regulator_check_states(state) || state == PM_SUSPEND_ON) |
3400 | return -EINVAL; | 3455 | return -EINVAL; |
3401 | 3456 | ||
3402 | regulator_lock_supply(regulator->rdev); | 3457 | regulator_lock_dependent(regulator->rdev); |
3403 | 3458 | ||
3404 | ret = _regulator_set_suspend_voltage(regulator, min_uV, | 3459 | ret = _regulator_set_suspend_voltage(regulator, min_uV, |
3405 | max_uV, state); | 3460 | max_uV, state); |
3406 | 3461 | ||
3407 | regulator_unlock_supply(regulator->rdev); | 3462 | regulator_unlock_dependent(regulator->rdev); |
3408 | 3463 | ||
3409 | return ret; | 3464 | return ret; |
3410 | } | 3465 | } |
@@ -3596,11 +3651,11 @@ int regulator_get_voltage(struct regulator *regulator) | |||
3596 | { | 3651 | { |
3597 | int ret; | 3652 | int ret; |
3598 | 3653 | ||
3599 | regulator_lock_supply(regulator->rdev); | 3654 | regulator_lock_dependent(regulator->rdev); |
3600 | 3655 | ||
3601 | ret = _regulator_get_voltage(regulator->rdev); | 3656 | ret = _regulator_get_voltage(regulator->rdev); |
3602 | 3657 | ||
3603 | regulator_unlock_supply(regulator->rdev); | 3658 | regulator_unlock_dependent(regulator->rdev); |
3604 | 3659 | ||
3605 | return ret; | 3660 | return ret; |
3606 | } | 3661 | } |