@@ -107,6 +107,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
107
107
int min_uV , int max_uV );
108
108
static int regulator_balance_voltage (struct regulator_dev * rdev ,
109
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
113
static struct regulator * create_regulator (struct regulator_dev * rdev ,
111
114
struct device * dev ,
112
115
const char * supply_name );
@@ -198,37 +201,66 @@ static void regulator_unlock(struct regulator_dev *rdev)
198
201
}
199
202
}
200
203
201
- /**
202
- * regulator_lock_supply - lock a regulator and its supplies
203
- * @rdev: regulator source
204
- */
205
- static void regulator_lock_supply (struct regulator_dev * rdev )
204
+ static int regulator_lock_recursive (struct regulator_dev * rdev ,
205
+ unsigned int subclass )
206
206
{
207
+ struct regulator_dev * c_rdev ;
207
208
int i ;
208
209
209
- for (i = 0 ; rdev ; rdev = rdev_get_supply (rdev ), i ++ )
210
- regulator_lock_nested (rdev , i );
210
+ for (i = 0 ; i < rdev -> coupling_desc .n_coupled ; 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
215
- * @rdev: regulator source
228
+ * regulator_unlock_dependent - unlock regulator's suppliers and coupled
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 ) {
222
- regulator_unlock (rdev );
223
- supply = rdev -> supply ;
239
+ for (i = 0 ; i < rdev -> coupling_desc .n_coupled ; i ++ ) {
240
+ c_rdev = rdev -> coupling_desc .coupled_rdevs [i ];
224
241
225
- if (!rdev -> supply )
226
- return ;
242
+ if (!c_rdev )
243
+ continue ;
227
244
228
- rdev = supply -> rdev ;
245
+ regulator_unlock (c_rdev );
246
+
247
+ if (c_rdev -> supply )
248
+ regulator_unlock_dependent (c_rdev -> supply -> rdev );
229
249
}
230
250
}
231
251
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
+
232
264
/**
233
265
* of_get_regulator - get a regulator device node based on supply name
234
266
* @dev: Device pointer for the consumer (of regulator) device
@@ -2289,9 +2321,16 @@ int regulator_enable(struct regulator *regulator)
2289
2321
return ret ;
2290
2322
}
2291
2323
2292
- mutex_lock (& rdev -> mutex );
2324
+ regulator_lock_dependent (rdev );
2325
+ /* balance only if there are regulators coupled */
2326
+ if (rdev -> coupling_desc .n_coupled > 1 ) {
2327
+ ret = regulator_balance_voltage (rdev , PM_SUSPEND_ON );
2328
+ if (ret != 0 )
2329
+ goto unlock ;
2330
+ }
2293
2331
ret = _regulator_enable (rdev );
2294
- mutex_unlock (& rdev -> mutex );
2332
+ unlock :
2333
+ regulator_unlock_dependent (rdev );
2295
2334
2296
2335
if (ret != 0 && rdev -> supply )
2297
2336
regulator_disable (rdev -> supply );
@@ -2397,9 +2436,11 @@ int regulator_disable(struct regulator *regulator)
2397
2436
if (regulator -> always_on )
2398
2437
return 0 ;
2399
2438
2400
- mutex_lock ( & rdev -> mutex );
2439
+ regulator_lock_dependent ( rdev );
2401
2440
ret = _regulator_disable (rdev );
2402
- mutex_unlock (& rdev -> mutex );
2441
+ if (rdev -> coupling_desc .n_coupled > 1 )
2442
+ regulator_balance_voltage (rdev , PM_SUSPEND_ON );
2443
+ regulator_unlock_dependent (rdev );
2403
2444
2404
2445
if (ret == 0 && rdev -> supply )
2405
2446
regulator_disable (rdev -> supply );
@@ -2448,10 +2489,12 @@ int regulator_force_disable(struct regulator *regulator)
2448
2489
struct regulator_dev * rdev = regulator -> rdev ;
2449
2490
int ret ;
2450
2491
2451
- mutex_lock ( & rdev -> mutex );
2492
+ regulator_lock_dependent ( rdev );
2452
2493
regulator -> uA_load = 0 ;
2453
2494
ret = _regulator_force_disable (regulator -> rdev );
2454
- mutex_unlock (& rdev -> mutex );
2495
+ if (rdev -> coupling_desc .n_coupled > 1 )
2496
+ regulator_balance_voltage (rdev , PM_SUSPEND_ON );
2497
+ regulator_unlock_dependent (rdev );
2455
2498
2456
2499
if (rdev -> supply )
2457
2500
while (rdev -> open_count -- )
@@ -2599,9 +2642,9 @@ int regulator_is_enabled(struct regulator *regulator)
2599
2642
if (regulator -> always_on )
2600
2643
return 1 ;
2601
2644
2602
- mutex_lock ( & regulator -> rdev -> mutex );
2645
+ regulator_lock_dependent ( regulator -> rdev );
2603
2646
ret = _regulator_is_enabled (regulator -> rdev );
2604
- mutex_unlock ( & regulator -> rdev -> mutex );
2647
+ regulator_unlock_dependent ( regulator -> rdev );
2605
2648
2606
2649
return ret ;
2607
2650
}
@@ -3015,8 +3058,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3015
3058
int ret = 0 ;
3016
3059
int old_min_uV , old_max_uV ;
3017
3060
int current_uV ;
3018
- int best_supply_uV = 0 ;
3019
- int supply_change_uV = 0 ;
3020
3061
3021
3062
/* If we're setting the same range as last time the change
3022
3063
* should be a noop (some cpufreq implementations use the same
@@ -3056,10 +3097,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3056
3097
voltage -> min_uV = min_uV ;
3057
3098
voltage -> max_uV = max_uV ;
3058
3099
3059
- ret = regulator_check_consumers (rdev , & min_uV , & max_uV , state );
3100
+ /* for not coupled regulators this will just set the voltage */
3101
+ ret = regulator_balance_voltage (rdev , state );
3060
3102
if (ret < 0 )
3061
3103
goto out2 ;
3062
3104
3105
+ out :
3106
+ return 0 ;
3107
+ out2 :
3108
+ voltage -> min_uV = old_min_uV ;
3109
+ voltage -> max_uV = old_max_uV ;
3110
+
3111
+ return ret ;
3112
+ }
3113
+
3114
+ static int regulator_set_voltage_rdev (struct regulator_dev * rdev , int min_uV ,
3115
+ int max_uV , suspend_state_t state )
3116
+ {
3117
+ int best_supply_uV = 0 ;
3118
+ int supply_change_uV = 0 ;
3119
+ int ret ;
3120
+
3063
3121
if (rdev -> supply &&
3064
3122
regulator_ops_is_valid (rdev -> supply -> rdev ,
3065
3123
REGULATOR_CHANGE_VOLTAGE ) &&
@@ -3071,21 +3129,21 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3071
3129
selector = regulator_map_voltage (rdev , min_uV , max_uV );
3072
3130
if (selector < 0 ) {
3073
3131
ret = selector ;
3074
- goto out2 ;
3132
+ goto out ;
3075
3133
}
3076
3134
3077
3135
best_supply_uV = _regulator_list_voltage (rdev , selector , 0 );
3078
3136
if (best_supply_uV < 0 ) {
3079
3137
ret = best_supply_uV ;
3080
- goto out2 ;
3138
+ goto out ;
3081
3139
}
3082
3140
3083
3141
best_supply_uV += rdev -> desc -> min_dropout_uV ;
3084
3142
3085
3143
current_supply_uV = _regulator_get_voltage (rdev -> supply -> rdev );
3086
3144
if (current_supply_uV < 0 ) {
3087
3145
ret = current_supply_uV ;
3088
- goto out2 ;
3146
+ goto out ;
3089
3147
}
3090
3148
3091
3149
supply_change_uV = best_supply_uV - current_supply_uV ;
@@ -3097,7 +3155,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3097
3155
if (ret ) {
3098
3156
dev_err (& rdev -> dev , "Failed to increase supply voltage: %d\n" ,
3099
3157
ret );
3100
- goto out2 ;
3158
+ goto out ;
3101
3159
}
3102
3160
}
3103
3161
@@ -3107,7 +3165,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3107
3165
ret = _regulator_do_set_suspend_voltage (rdev , min_uV ,
3108
3166
max_uV , state );
3109
3167
if (ret < 0 )
3110
- goto out2 ;
3168
+ goto out ;
3111
3169
3112
3170
if (supply_change_uV < 0 ) {
3113
3171
ret = regulator_set_voltage_unlocked (rdev -> supply ,
@@ -3120,11 +3178,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
3120
3178
}
3121
3179
3122
3180
out :
3123
- return ret ;
3124
- out2 :
3125
- voltage -> min_uV = old_min_uV ;
3126
- voltage -> max_uV = old_max_uV ;
3127
-
3128
3181
return ret ;
3129
3182
}
3130
3183
@@ -3340,10 +3393,10 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
3340
3393
ret = 0 ;
3341
3394
goto out ;
3342
3395
}
3343
- #if 0
3396
+
3344
3397
ret = regulator_set_voltage_rdev (best_rdev , best_min_uV ,
3345
3398
best_max_uV , state );
3346
- #endif
3399
+
3347
3400
if (ret < 0 )
3348
3401
goto out ;
3349
3402
@@ -3377,12 +3430,12 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
3377
3430
{
3378
3431
int ret = 0 ;
3379
3432
3380
- regulator_lock_supply (regulator -> rdev );
3433
+ regulator_lock_dependent (regulator -> rdev );
3381
3434
3382
3435
ret = regulator_set_voltage_unlocked (regulator , min_uV , max_uV ,
3383
3436
PM_SUSPEND_ON );
3384
3437
3385
- regulator_unlock_supply (regulator -> rdev );
3438
+ regulator_unlock_dependent (regulator -> rdev );
3386
3439
3387
3440
return ret ;
3388
3441
}
@@ -3460,12 +3513,12 @@ int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
3460
3513
if (regulator_check_states (state ) || state == PM_SUSPEND_ON )
3461
3514
return - EINVAL ;
3462
3515
3463
- regulator_lock_supply (regulator -> rdev );
3516
+ regulator_lock_dependent (regulator -> rdev );
3464
3517
3465
3518
ret = _regulator_set_suspend_voltage (regulator , min_uV ,
3466
3519
max_uV , state );
3467
3520
3468
- regulator_unlock_supply (regulator -> rdev );
3521
+ regulator_unlock_dependent (regulator -> rdev );
3469
3522
3470
3523
return ret ;
3471
3524
}
@@ -3657,11 +3710,11 @@ int regulator_get_voltage(struct regulator *regulator)
3657
3710
{
3658
3711
int ret ;
3659
3712
3660
- regulator_lock_supply (regulator -> rdev );
3713
+ regulator_lock_dependent (regulator -> rdev );
3661
3714
3662
3715
ret = _regulator_get_voltage (regulator -> rdev );
3663
3716
3664
- regulator_unlock_supply (regulator -> rdev );
3717
+ regulator_unlock_dependent (regulator -> rdev );
3665
3718
3666
3719
return ret ;
3667
3720
}
0 commit comments