-}
-
-static int regulator_get_optimal_voltage(struct regulator_dev *rdev)
-{
- struct coupling_desc *c_desc = &rdev->coupling_desc;
- struct regulator_dev **c_rdevs = c_desc->coupled_rdevs;
- int max_spread = rdev->constraints->max_spread;
- int n_coupled = c_desc->n_coupled;
- int desired_min_uV, desired_max_uV, min_current_uV = INT_MAX;
- int max_current_uV = 0, highest_min_uV = 0, target_uV, possible_uV;
- int i, ret;
-
- /* If consumers don't provide any demands, set voltage to min_uV */
- desired_min_uV = rdev->constraints->min_uV;
- desired_max_uV = rdev->constraints->max_uV;
- ret = regulator_check_consumers(rdev,
- &desired_min_uV,
- &desired_max_uV, PM_SUSPEND_ON);
- if (ret < 0)
- goto out;
-
- /*
- * If there are no coupled regulators, simply set the voltage demanded
- * by consumers.
- */
- if (n_coupled == 1) {
- ret = desired_min_uV;
- goto out;
- }
-
- /* Find highest min desired voltage */
- for (i = 0; i < n_coupled; i++) {
- int tmp_min = 0;
- int tmp_max = INT_MAX;
-
- if (!_regulator_is_enabled(c_rdevs[i]))
- continue;
-
- ret = regulator_check_consumers(c_rdevs[i],
- &tmp_min,
- &tmp_max, PM_SUSPEND_ON);
- if (ret < 0)
- goto out;
-
- if (tmp_min > highest_min_uV)
- highest_min_uV = tmp_min;
- }
-
- /*
- * Let target_uV be equal to the desired one if possible.
- * If not, set it to minimum voltage, allowed by other coupled
- * regulators.
- */
- target_uV = max(desired_min_uV, highest_min_uV - max_spread);
-
- /*
- * Find min and max voltages, which currently aren't
- * violating max_spread
- */
- for (i = 0; i < n_coupled; i++) {
- int tmp_act;
-
- /*
- * Don't check the regulator, which is about
- * to change voltage
- */
- if (c_rdevs[i] == rdev)
- continue;
- if (!_regulator_is_enabled(c_rdevs[i]))
- continue;
-
- tmp_act = _regulator_get_voltage(c_rdevs[i]);
- if (tmp_act < 0) {
- ret = tmp_act;
- goto out;
- }
-
- if (tmp_act < min_current_uV)
- min_current_uV = tmp_act;
-
- if (tmp_act > max_current_uV)
- max_current_uV = tmp_act;
- }
-
- /* There aren't any other regulators enabled */
- if (max_current_uV == 0) {
- possible_uV = target_uV;
- } else {
- /*
- * Correct target voltage, so as it currently isn't
- * violating max_spread
- */
- possible_uV = max(target_uV, max_current_uV - max_spread);
- possible_uV = min(possible_uV, min_current_uV + max_spread);
- }
-
- if (possible_uV > desired_max_uV) {
- ret = -EINVAL;
- goto out;
- }
- ret = possible_uV;
-
-out:
- return ret;
-}
-
-static int regulator_balance_voltage(struct regulator_dev *rdev,
- suspend_state_t state)
-{
- struct regulator_dev **c_rdevs;
- struct regulator_dev *best_rdev;
- struct coupling_desc *c_desc = &rdev->coupling_desc;
- int n_coupled;
- int i, best_delta, best_uV, ret = 1;
-
- c_rdevs = c_desc->coupled_rdevs;
- n_coupled = c_desc->n_coupled;
-
- /*
- * if system is in a state other than PM_SUSPEND_ON, don't check
- * other coupled regulators
- */
- if (state != PM_SUSPEND_ON)
- n_coupled = 1;
-
- /*
- * Find the best possible voltage change on each loop. Leave the loop
- * if there isn't any possible change.
- */
- while (1) {
- best_delta = 0;
- best_uV = 0;
- best_rdev = NULL;
-
- /*
- * Find highest difference between optimal voltage
- * and current voltage.
- */
- for (i = 0; i < n_coupled; i++) {
- /*
- * optimal_uV is the best voltage that can be set for
- * i-th regulator at the moment without violating
- * max_spread constraint in order to balance
- * the coupled voltages.
- */
- int optimal_uV, current_uV;
-
- optimal_uV = regulator_get_optimal_voltage(c_rdevs[i]);
- if (optimal_uV < 0) {
- ret = optimal_uV;
- goto out;
- }
-
- current_uV = _regulator_get_voltage(c_rdevs[i]);
- if (current_uV < 0) {
- ret = optimal_uV;
- goto out;
- }
-
- if (abs(best_delta) < abs(optimal_uV - current_uV)) {
- best_delta = optimal_uV - current_uV;
- best_rdev = c_rdevs[i];
- best_uV = optimal_uV;
- }
- }
-
- /* Nothing to change, return successfully */
- if (!best_rdev) {
- ret = 0;
- goto out;
- }
-
- ret = regulator_set_voltage_rdev(best_rdev, best_uV,
- best_uV, state);
-
- if (ret < 0)
- goto out;
- }