aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaciej Purski <m.purski@samsung.com>2018-04-23 10:33:42 -0400
committerMark Brown <broonie@kernel.org>2018-05-17 03:05:51 -0400
commit456e7cdf3b1a14e2606b8b687385ab2e3f23a49a (patch)
tree4e2dd59031c7112142205dc0c116019872c1be10
parent696861761a58d8c93605b5663824929fb6540f16 (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.c159
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);
108static int regulator_balance_voltage(struct regulator_dev *rdev, 108static int regulator_balance_voltage(struct regulator_dev *rdev,
109 suspend_state_t state); 109 suspend_state_t state);
110static int regulator_set_voltage_rdev(struct regulator_dev *rdev,
111 int min_uV, int max_uV,
112 suspend_state_t state);
110static struct regulator *create_regulator(struct regulator_dev *rdev, 113static 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/** 204static 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 */
205static 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 */
217static void regulator_unlock_supply(struct regulator_dev *rdev) 234static 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 */
259static 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(&regulator->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(&regulator->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
3092out:
3093 return 0;
3094out2:
3095 voltage->min_uV = old_min_uV;
3096 voltage->max_uV = old_max_uV;
3097
3098 return ret;
3099}
3100
3101static 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
3098out: 3167out:
3099 return ret; 3168 return ret;
3100out2:
3101 voltage->min_uV = old_min_uV;
3102 voltage->max_uV = old_max_uV;
3103
3104 return ret;
3105} 3169}
3106 3170
3107static int regulator_get_optimal_voltage(struct regulator_dev *rdev) 3171static 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}