Commit ffb8c1e4 authored by Mark Brown's avatar Mark Brown

Merge branch 'topic/coupled' of...

Merge branch 'topic/coupled' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into regulator-4.21 for trivial conflict
parents a8d8ee43 ff9b34b6
......@@ -82,6 +82,8 @@ Optional properties:
- regulator-coupled-max-spread: Array of maximum spread between voltages of
coupled regulators in microvolts, each value in the array relates to the
corresponding couple specified by the regulator-coupled-with property.
- regulator-max-step-microvolt: Maximum difference between current and target
voltages that can be changed safely in a single step.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple
......
......@@ -50,6 +50,8 @@
#define rdev_dbg(rdev, fmt, ...) \
pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
static DEFINE_WW_CLASS(regulator_ww_class);
static DEFINE_MUTEX(regulator_nesting_mutex);
static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_map_list);
static LIST_HEAD(regulator_ena_gpio_list);
......@@ -105,6 +107,11 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV);
static int regulator_balance_voltage(struct regulator_dev *rdev,
suspend_state_t state);
static int regulator_set_voltage_rdev(struct regulator_dev *rdev,
int min_uV, int max_uV,
suspend_state_t state);
static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name);
......@@ -149,7 +156,7 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
/**
* regulator_lock_nested - lock a single regulator
* @rdev: regulator source
* @subclass: mutex subclass used for lockdep
* @ww_ctx: w/w mutex acquire context
*
* This function can be called many times by one task on
* a single regulator and its mutex will be locked only
......@@ -157,24 +164,52 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
* than the one, which initially locked the mutex, it will
* wait on mutex.
*/
static void regulator_lock_nested(struct regulator_dev *rdev,
unsigned int subclass)
static inline int regulator_lock_nested(struct regulator_dev *rdev,
struct ww_acquire_ctx *ww_ctx)
{
if (!mutex_trylock(&rdev->mutex)) {
if (rdev->mutex_owner == current) {
bool lock = false;
int ret = 0;
mutex_lock(&regulator_nesting_mutex);
if (ww_ctx || !ww_mutex_trylock(&rdev->mutex)) {
if (rdev->mutex_owner == current)
rdev->ref_cnt++;
return;
else
lock = true;
if (lock) {
mutex_unlock(&regulator_nesting_mutex);
ret = ww_mutex_lock(&rdev->mutex, ww_ctx);
mutex_lock(&regulator_nesting_mutex);
}
mutex_lock_nested(&rdev->mutex, subclass);
} else {
lock = true;
}
rdev->ref_cnt = 1;
rdev->mutex_owner = current;
if (lock && ret != -EDEADLK) {
rdev->ref_cnt++;
rdev->mutex_owner = current;
}
mutex_unlock(&regulator_nesting_mutex);
return ret;
}
static inline void regulator_lock(struct regulator_dev *rdev)
/**
* regulator_lock - lock a single regulator
* @rdev: regulator source
*
* This function can be called many times by one task on
* a single regulator and its mutex will be locked only
* once. If a task, which is calling this function is other
* than the one, which initially locked the mutex, it will
* wait on mutex.
*/
void regulator_lock(struct regulator_dev *rdev)
{
regulator_lock_nested(rdev, 0);
regulator_lock_nested(rdev, NULL);
}
/**
......@@ -184,47 +219,159 @@ static inline void regulator_lock(struct regulator_dev *rdev)
* This function unlocks the mutex when the
* reference counter reaches 0.
*/
static void regulator_unlock(struct regulator_dev *rdev)
void regulator_unlock(struct regulator_dev *rdev)
{
mutex_lock(&regulator_nesting_mutex);
if (--rdev->ref_cnt == 0) {
rdev->mutex_owner = NULL;
ww_mutex_unlock(&rdev->mutex);
}
WARN_ON_ONCE(rdev->ref_cnt < 0);
mutex_unlock(&regulator_nesting_mutex);
}
static bool regulator_supply_is_couple(struct regulator_dev *rdev)
{
if (rdev->ref_cnt != 0) {
rdev->ref_cnt--;
struct regulator_dev *c_rdev;
int i;
for (i = 1; i < rdev->coupling_desc.n_coupled; i++) {
c_rdev = rdev->coupling_desc.coupled_rdevs[i];
if (!rdev->ref_cnt) {
rdev->mutex_owner = NULL;
mutex_unlock(&rdev->mutex);
if (rdev->supply->rdev == c_rdev)
return true;
}
return false;
}
static void regulator_unlock_recursive(struct regulator_dev *rdev,
unsigned int n_coupled)
{
struct regulator_dev *c_rdev;
int i;
for (i = n_coupled; i > 0; i--) {
c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1];
if (!c_rdev)
continue;
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev))
regulator_unlock_recursive(
c_rdev->supply->rdev,
c_rdev->coupling_desc.n_coupled);
regulator_unlock(c_rdev);
}
}
static int regulator_lock_recursive(struct regulator_dev *rdev,
struct regulator_dev **new_contended_rdev,
struct regulator_dev **old_contended_rdev,
struct ww_acquire_ctx *ww_ctx)
{
struct regulator_dev *c_rdev;
int i, err;
for (i = 0; i < rdev->coupling_desc.n_coupled; i++) {
c_rdev = rdev->coupling_desc.coupled_rdevs[i];
if (!c_rdev)
continue;
if (c_rdev != *old_contended_rdev) {
err = regulator_lock_nested(c_rdev, ww_ctx);
if (err) {
if (err == -EDEADLK) {
*new_contended_rdev = c_rdev;
goto err_unlock;
}
/* shouldn't happen */
WARN_ON_ONCE(err != -EALREADY);
}
} else {
*old_contended_rdev = NULL;
}
if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) {
err = regulator_lock_recursive(c_rdev->supply->rdev,
new_contended_rdev,
old_contended_rdev,
ww_ctx);
if (err) {
regulator_unlock(c_rdev);
goto err_unlock;
}
}
}
return 0;
err_unlock:
regulator_unlock_recursive(rdev, i);
return err;
}
/**
* regulator_lock_supply - lock a regulator and its supplies
* @rdev: regulator source
* regulator_unlock_dependent - unlock regulator's suppliers and coupled
* regulators
* @rdev: regulator source
* @ww_ctx: w/w mutex acquire context
*
* Unlock all regulators related with rdev by coupling or suppling.
*/
static void regulator_lock_supply(struct regulator_dev *rdev)
static void regulator_unlock_dependent(struct regulator_dev *rdev,
struct ww_acquire_ctx *ww_ctx)
{
int i;
for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
regulator_lock_nested(rdev, i);
regulator_unlock_recursive(rdev, rdev->coupling_desc.n_coupled);
ww_acquire_fini(ww_ctx);
}
/**
* regulator_unlock_supply - unlock a regulator and its supplies
* @rdev: regulator source
* regulator_lock_dependent - lock regulator's suppliers and coupled regulators
* @rdev: regulator source
* @ww_ctx: w/w mutex acquire context
*
* This function as a wrapper on regulator_lock_recursive(), which locks
* all regulators related with rdev by coupling or suppling.
*/
static void regulator_unlock_supply(struct regulator_dev *rdev)
static void regulator_lock_dependent(struct regulator_dev *rdev,
struct ww_acquire_ctx *ww_ctx)
{
struct regulator *supply;
struct regulator_dev *new_contended_rdev = NULL;
struct regulator_dev *old_contended_rdev = NULL;
int err;
while (1) {
regulator_unlock(rdev);
supply = rdev->supply;
mutex_lock(&regulator_list_mutex);
if (!rdev->supply)
return;
ww_acquire_init(ww_ctx, &regulator_ww_class);
rdev = supply->rdev;
}
do {
if (new_contended_rdev) {
ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
old_contended_rdev = new_contended_rdev;
old_contended_rdev->ref_cnt++;
}
err = regulator_lock_recursive(rdev,
&new_contended_rdev,
&old_contended_rdev,
ww_ctx);
if (old_contended_rdev)
regulator_unlock(old_contended_rdev);
} while (err == -EDEADLK);
ww_acquire_done(ww_ctx);
mutex_unlock(&regulator_list_mutex);
}
/**
......@@ -773,7 +920,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
int current_uA = 0, output_uV, input_uV, err;
unsigned int mode;
lockdep_assert_held_once(&rdev->mutex);
lockdep_assert_held_once(&rdev->mutex.base);
/*
* first check to see if we can set modes at all, otherwise just
......@@ -1748,6 +1895,16 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
return regulator;
}
mutex_lock(&regulator_list_mutex);
ret = (rdev->coupling_desc.n_resolved != rdev->coupling_desc.n_coupled);
mutex_unlock(&regulator_list_mutex);
if (ret != 0) {
regulator = ERR_PTR(-EPROBE_DEFER);
put_device(&rdev->dev);
return regulator;
}
ret = regulator_resolve_supply(rdev);
if (ret < 0) {
regulator = ERR_PTR(ret);
......@@ -2265,7 +2422,20 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
int ret;
lockdep_assert_held_once(&rdev->mutex);
lockdep_assert_held_once(&rdev->mutex.base);
if (rdev->supply) {
ret = _regulator_enable(rdev->supply->rdev);
if (ret < 0)
return ret;
}
/* balance only if there are regulators coupled */
if (rdev->coupling_desc.n_coupled > 1) {
ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
if (ret < 0)
goto err_disable_supply;
}
/* check voltage and requested load before enabling */
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
......@@ -2276,18 +2446,20 @@ static int _regulator_enable(struct regulator_dev *rdev)
ret = _regulator_is_enabled(rdev);
if (ret == -EINVAL || ret == 0) {
if (!regulator_ops_is_valid(rdev,
REGULATOR_CHANGE_STATUS))
return -EPERM;
REGULATOR_CHANGE_STATUS)) {
ret = -EPERM;
goto err_disable_supply;
}
ret = _regulator_do_enable(rdev);
if (ret < 0)
return ret;
goto err_disable_supply;
_notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE,
NULL);
} else if (ret < 0) {
rdev_err(rdev, "is_enabled() failed: %d\n", ret);
return ret;
goto err_disable_supply;
}
/* Fallthrough on positive return values - already enabled */
}
......@@ -2295,6 +2467,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
rdev->use_count++;
return 0;
err_disable_supply:
if (rdev->supply)
_regulator_disable(rdev->supply->rdev);
return ret;
}
/**
......@@ -2311,23 +2489,15 @@ static int _regulator_enable(struct regulator_dev *rdev)
int regulator_enable(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret = 0;
if (regulator->always_on)
return 0;
if (rdev->supply) {
ret = regulator_enable(rdev->supply);
if (ret != 0)
return ret;
}
mutex_lock(&rdev->mutex);
regulator_lock_dependent(rdev, &ww_ctx);
ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex);
if (ret != 0 && rdev->supply)
regulator_disable(rdev->supply);
regulator_unlock_dependent(rdev, &ww_ctx);
return ret;
}
......@@ -2369,7 +2539,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
int ret = 0;
lockdep_assert_held_once(&rdev->mutex);
lockdep_assert_held_once(&rdev->mutex.base);
if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n", rdev_get_name(rdev)))
......@@ -2407,6 +2577,12 @@ static int _regulator_disable(struct regulator_dev *rdev)
rdev->use_count--;
}
if (ret == 0 && rdev->coupling_desc.n_coupled > 1)
ret = regulator_balance_voltage(rdev, PM_SUSPEND_ON);
if (ret == 0 && rdev->supply)
ret = _regulator_disable(rdev->supply->rdev);
return ret;
}
......@@ -2425,17 +2601,15 @@ static int _regulator_disable(struct regulator_dev *rdev)
int regulator_disable(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret = 0;
if (regulator->always_on)
return 0;
mutex_lock(&rdev->mutex);
regulator_lock_dependent(rdev, &ww_ctx);
ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex);
if (ret == 0 && rdev->supply)
regulator_disable(rdev->supply);
regulator_unlock_dependent(rdev, &ww_ctx);
return ret;
}
......@@ -2446,7 +2620,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{
int ret = 0;
lockdep_assert_held_once(&rdev->mutex);
lockdep_assert_held_once(&rdev->mutex.base);
ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_PRE_DISABLE, NULL);
......@@ -2479,12 +2653,15 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
int regulator_force_disable(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret;
mutex_lock(&rdev->mutex);
regulator_lock_dependent(rdev, &ww_ctx);
regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev);
mutex_unlock(&rdev->mutex);
if (rdev->coupling_desc.n_coupled > 1)
regulator_balance_voltage(rdev, PM_SUSPEND_ON);
regulator_unlock_dependent(rdev, &ww_ctx);
if (rdev->supply)
while (rdev->open_count--)
......@@ -2498,9 +2675,10 @@ static void regulator_disable_work(struct work_struct *work)
{
struct regulator_dev *rdev = container_of(work, struct regulator_dev,
disable_work.work);
struct ww_acquire_ctx ww_ctx;
int count, i, ret;
regulator_lock(rdev);
regulator_lock_dependent(rdev, &ww_ctx);
BUG_ON(!rdev->deferred_disables);
......@@ -2521,7 +2699,10 @@ static void regulator_disable_work(struct work_struct *work)
rdev_err(rdev, "Deferred disable failed: %d\n", ret);
}
regulator_unlock(rdev);
if (rdev->coupling_desc.n_coupled > 1)
regulator_balance_voltage(rdev, PM_SUSPEND_ON);
regulator_unlock_dependent(rdev, &ww_ctx);
if (rdev->supply) {
for (i = 0; i < count; i++) {
......@@ -2632,9 +2813,9 @@ int regulator_is_enabled(struct regulator *regulator)
if (regulator->always_on)
return 1;
mutex_lock(&regulator->rdev->mutex);
regulator_lock(regulator->rdev);
ret = _regulator_is_enabled(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
regulator_unlock(regulator->rdev);
return ret;
}
......@@ -3048,8 +3229,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
int ret = 0;
int old_min_uV, old_max_uV;
int current_uV;
int best_supply_uV = 0;
int supply_change_uV = 0;
/* If we're setting the same range as last time the change
* should be a noop (some cpufreq implementations use the same
......@@ -3089,10 +3268,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
voltage->min_uV = min_uV;
voltage->max_uV = max_uV;
ret = regulator_check_consumers(rdev, &min_uV, &max_uV, state);
/* for not coupled regulators this will just set the voltage */
ret = regulator_balance_voltage(rdev, state);
if (ret < 0)
goto out2;
out:
return 0;
out2:
voltage->min_uV = old_min_uV;
voltage->max_uV = old_max_uV;
return ret;
}
static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
int max_uV, suspend_state_t state)
{
int best_supply_uV = 0;
int supply_change_uV = 0;
int ret;
if (rdev->supply &&
regulator_ops_is_valid(rdev->supply->rdev,
REGULATOR_CHANGE_VOLTAGE) &&
......@@ -3104,13 +3300,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
selector = regulator_map_voltage(rdev, min_uV, max_uV);
if (selector < 0) {
ret = selector;
goto out2;
goto out;
}
best_supply_uV = _regulator_list_voltage(rdev, selector, 0);
if (best_supply_uV < 0) {
ret = best_supply_uV;
goto out2;
goto out;
}
best_supply_uV += rdev->desc->min_dropout_uV;
......@@ -3118,7 +3314,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);
if (current_supply_uV < 0) {
ret = current_supply_uV;
goto out2;
goto out;
}
supply_change_uV = best_supply_uV - current_supply_uV;
......@@ -3130,7 +3326,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
if (ret) {
dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
ret);
goto out2;
goto out;
}
}
......@@ -3140,7 +3336,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
ret = _regulator_do_set_suspend_voltage(rdev, min_uV,
max_uV, state);
if (ret < 0)
goto out2;
goto out;
if (supply_change_uV < 0) {
ret = regulator_set_voltage_unlocked(rdev->supply,
......@@ -3154,10 +3350,273 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
out:
return ret;
out2:
voltage->min_uV = old_min_uV;
voltage->max_uV = old_max_uV;
}
static int regulator_limit_voltage_step(struct regulator_dev *rdev,
int *current_uV, int *min_uV)
{
struct regulation_constraints *constraints = rdev->constraints;
/* Limit voltage change only if necessary */
if (!constraints->max_uV_step || !_regulator_is_enabled(rdev))
return 1;
if (*current_uV < 0) {
*current_uV = _regulator_get_voltage(rdev);
if (*current_uV < 0)
return *current_uV;
}
if (abs(*current_uV - *min_uV) <= constraints->max_uV_step)
return 1;
/* Clamp target voltage within the given step */
if (*current_uV < *min_uV)
*min_uV = min(*current_uV + constraints->max_uV_step,
*min_uV);
else
*min_uV = max(*current_uV - constraints->max_uV_step,
*min_uV);
return 0;
}
static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
int *current_uV,
int *min_uV, int *max_uV,
suspend_state_t state,
int n_coupled)
{
struct coupling_desc *c_desc = &rdev->coupling_desc;
struct regulator_dev **c_rdevs = c_desc->coupled_rdevs;
struct regulation_constraints *constraints = rdev->constraints;
int max_spread = constraints->max_spread;
int desired_min_uV = 0, desired_max_uV = INT_MAX;
int max_current_uV = 0, min_current_uV = INT_MAX;
int highest_min_uV = 0, target_uV, possible_uV;
int i, ret;
bool done;
*current_uV = -1;
/*
* If there are no coupled regulators, simply set the voltage
* demanded by consumers.
*/
if (n_coupled == 1) {
/*
* If consumers don't provide any demands, set voltage
* to min_uV
*/
desired_min_uV = constraints->min_uV;
desired_max_uV = constraints->max_uV;
ret = regulator_check_consumers(rdev,
&desired_min_uV,
&desired_max_uV, state);
if (ret < 0)
return ret;
possible_uV = desired_min_uV;
done = true;
goto finish;
}
/* Find highest min desired voltage */
for (i = 0; i < n_coupled; i++) {
int tmp_min = 0;
int tmp_max = INT_MAX;
lockdep_assert_held_once(&c_rdevs[i]->mutex.base);
ret = regulator_check_consumers(c_rdevs[i],
&tmp_min,
&tmp_max, state);
if (ret < 0)
return ret;
ret = regulator_check_voltage(c_rdevs[i], &tmp_min, &tmp_max);
if (ret < 0)
return ret;
highest_min_uV = max(highest_min_uV, tmp_min);
if (i == 0) {
desired_min_uV = tmp_min;
desired_max_uV = tmp_max;
}
}
/*
* 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 = 1; i < n_coupled; i++) {
int tmp_act;
if (!_regulator_is_enabled(c_rdevs[i]))
continue;
tmp_act = _regulator_get_voltage(c_rdevs[i]);
if (tmp_act < 0)
return tmp_act;
min_current_uV = min(tmp_act, min_current_uV);
max_current_uV = max(tmp_act, max_current_uV);
}
/* 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)
return -EINVAL;
done = (possible_uV == target_uV);
desired_min_uV = possible_uV;
finish:
/* Apply max_uV_step constraint if necessary */
if (state == PM_SUSPEND_ON) {
ret = regulator_limit_voltage_step(rdev, current_uV,
&desired_min_uV);
if (ret < 0)
return ret;
if (ret == 0)
done = false;
}
/* Set current_uV if wasn't done earlier in the code and if necessary */
if (n_coupled > 1 && *current_uV == -1) {
if (_regulator_is_enabled(rdev)) {
ret = _regulator_get_voltage(rdev);
if (ret < 0)
return ret;
*current_uV = ret;
} else {
*current_uV = desired_min_uV;
}
}
*min_uV = desired_min_uV;
*max_uV = desired_max_uV;
return done;
}
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 i, ret, n_coupled, best_min_uV, best_max_uV, best_c_rdev;
bool best_c_rdev_done, c_rdev_done[MAX_COUPLED];
unsigned int delta, best_delta;
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;
if (c_desc->n_resolved < n_coupled) {
rdev_err(rdev, "Not all coupled regulators registered\n");
return -EPERM;
}
for (i = 0; i < n_coupled; i++)
c_rdev_done[i] = false;
/*
* Find the best possible voltage change on each loop. Leave the loop
* if there isn't any possible change.
*/
do {
best_c_rdev_done = false;
best_delta = 0;
best_min_uV = 0;
best_max_uV = 0;
best_c_rdev = 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 = 0, optimal_max_uV = 0, current_uV = 0;
if (c_rdev_done[i])
continue;
ret = regulator_get_optimal_voltage(c_rdevs[i],
&current_uV,
&optimal_uV,
&optimal_max_uV,
state, n_coupled);
if (ret < 0)
goto out;
delta = abs(optimal_uV - current_uV);
if (delta && best_delta <= delta) {
best_c_rdev_done = ret;
best_delta = delta;
best_rdev = c_rdevs[i];
best_min_uV = optimal_uV;
best_max_uV = optimal_max_uV;
best_c_rdev = i;
}
}
/* Nothing to change, return successfully */
if (!best_rdev) {
ret = 0;
goto out;
}
ret = regulator_set_voltage_rdev(best_rdev, best_min_uV,
best_max_uV, state);
if (ret < 0)
goto out;
c_rdev_done[best_c_rdev] = best_c_rdev_done;
} while (n_coupled > 1);
out:
return ret;
}
......@@ -3181,14 +3640,15 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
*/
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
{
int ret = 0;
struct ww_acquire_ctx ww_ctx;
int ret;
regulator_lock_supply(regulator->rdev);
regulator_lock_dependent(regulator->rdev, &ww_ctx);
ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
PM_SUSPEND_ON);
regulator_unlock_supply(regulator->rdev);
regulator_unlock_dependent(regulator->rdev, &ww_ctx);
return ret;
}
......@@ -3260,18 +3720,19 @@ static int _regulator_set_suspend_voltage(struct regulator *regulator,
int regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
int max_uV, suspend_state_t state)
{
int ret = 0;
struct ww_acquire_ctx ww_ctx;
int ret;
/* PM_SUSPEND_ON is handled by regulator_set_voltage() */
if (regulator_check_states(state) || state == PM_SUSPEND_ON)
return -EINVAL;
regulator_lock_supply(regulator->rdev);
regulator_lock_dependent(regulator->rdev, &ww_ctx);
ret = _regulator_set_suspend_voltage(regulator, min_uV,
max_uV, state);
regulator_unlock_supply(regulator->rdev);
regulator_unlock_dependent(regulator->rdev, &ww_ctx);
return ret;
}
......@@ -3461,13 +3922,12 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
*/
int regulator_get_voltage(struct regulator *regulator)
{
struct ww_acquire_ctx ww_ctx;
int ret;
regulator_lock_supply(regulator->rdev);
regulator_lock_dependent(regulator->rdev, &ww_ctx);
ret = _regulator_get_voltage(regulator->rdev);
regulator_unlock_supply(regulator->rdev);
regulator_unlock_dependent(regulator->rdev, &ww_ctx);
return ret;
}
......@@ -4003,7 +4463,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
lockdep_assert_held_once(&rdev->mutex);
lockdep_assert_held_once(&rdev->mutex.base);
_notifier_call_chain(rdev, event, data);
return NOTIFY_DONE;
......@@ -4192,7 +4652,7 @@ static int regulator_register_resolve_supply(struct device *dev, void *data)
return 0;
}
static int regulator_fill_coupling_array(struct regulator_dev *rdev)
static void regulator_resolve_coupling(struct regulator_dev *rdev)
{
struct coupling_desc *c_desc = &rdev->coupling_desc;
int n_coupled = c_desc->n_coupled;
......@@ -4206,33 +4666,58 @@ static int regulator_fill_coupling_array(struct regulator_dev *rdev)
c_rdev = of_parse_coupled_regulator(rdev, i - 1);
if (c_rdev) {
c_desc->coupled_rdevs[i] = c_rdev;
c_desc->n_resolved++;
}
}
if (!c_rdev)
continue;
if (rdev->coupling_desc.n_resolved < n_coupled)
return -1;
else
return 0;
regulator_lock(c_rdev);
c_desc->coupled_rdevs[i] = c_rdev;
c_desc->n_resolved++;
regulator_unlock(c_rdev);
regulator_resolve_coupling(c_rdev);
}
}
static int regulator_register_fill_coupling_array(struct device *dev,
void *data)
static void regulator_remove_coupling(struct regulator_dev *rdev)
{
struct regulator_dev *rdev = dev_to_rdev(dev);
struct coupling_desc *__c_desc, *c_desc = &rdev->coupling_desc;
struct regulator_dev *__c_rdev, *c_rdev;
unsigned int __n_coupled, n_coupled;
int i, k;
if (!IS_ENABLED(CONFIG_OF))
return 0;
n_coupled = c_desc->n_coupled;
if (regulator_fill_coupling_array(rdev))
rdev_dbg(rdev, "unable to resolve coupling\n");
for (i = 1; i < n_coupled; i++) {
c_rdev = c_desc->coupled_rdevs[i];
return 0;
if (!c_rdev)
continue;
regulator_lock(c_rdev);
__c_desc = &c_rdev->coupling_desc;
__n_coupled = __c_desc->n_coupled;
for (k = 1; k < __n_coupled; k++) {
__c_rdev = __c_desc->coupled_rdevs[k];
if (__c_rdev == rdev) {
__c_desc->coupled_rdevs[k] = NULL;
__c_desc->n_resolved--;
break;
}
}
regulator_unlock(c_rdev);
c_desc->coupled_rdevs[i] = NULL;
c_desc->n_resolved--;
}
}
static int regulator_resolve_coupling(struct regulator_dev *rdev)
static int regulator_init_coupling(struct regulator_dev *rdev)
{
int n_phandles;
......@@ -4272,13 +4757,6 @@ static int regulator_resolve_coupling(struct regulator_dev *rdev)
if (!of_check_coupling_data(rdev))
return -EPERM;
/*
* After everything has been checked, try to fill rdevs array
* with pointers to regulators parsed from device tree. If some
* regulators are not registered yet, retry in late init call
*/
regulator_fill_coupling_array(rdev);
return 0;
}
......@@ -4353,7 +4831,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev->dev.of_node = of_node_get(config->of_node);
}
mutex_init(&rdev->mutex);
ww_mutex_init(&rdev->mutex, &regulator_ww_class);
rdev->reg_data = config->driver_data;
rdev->owner = regulator_desc->owner;
rdev->desc = regulator_desc;
......@@ -4415,11 +4893,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0)
goto wash;
mutex_lock(&regulator_list_mutex);
ret = regulator_resolve_coupling(rdev);
mutex_unlock(&regulator_list_mutex);
if (ret != 0)
ret = regulator_init_coupling(rdev);
if (ret < 0)
goto wash;
/* add consumers devices */
......@@ -4453,6 +4928,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev_init_debugfs(rdev);
/* try to resolve regulators coupling since a new one was registered */
mutex_lock(&regulator_list_mutex);
regulator_resolve_coupling(rdev);
mutex_unlock(&regulator_list_mutex);
/* try to resolve regulators supply since a new one was registered */
class_for_each_device(&regulator_class, NULL, NULL,
regulator_register_resolve_supply);
......@@ -4491,15 +4971,19 @@ void regulator_unregister(struct regulator_dev *rdev)
regulator_disable(rdev->supply);
regulator_put(rdev->supply);
}
mutex_lock(&regulator_list_mutex);
debugfs_remove_recursive(rdev->debugfs);
flush_work(&rdev->disable_work.work);
WARN_ON(rdev->open_count);
regulator_remove_coupling(rdev);
unset_regulator_supplies(rdev);
list_del(&rdev->list);
regulator_ena_gpio_free(rdev);
mutex_unlock(&regulator_list_mutex);
device_unregister(&rdev->dev);
mutex_unlock(&regulator_list_mutex);
}
EXPORT_SYMBOL_GPL(regulator_unregister);
......@@ -4707,8 +5191,6 @@ static void regulator_summary_show_subtree(struct seq_file *s,
if (!rdev)
return;
regulator_lock_nested(rdev, level);
opmode = _regulator_get_mode_unlocked(rdev);
seq_printf(s, "%*s%-*s %3d %4d %6d %7s ",
level * 3 + 1, "",
......@@ -4765,8 +5247,105 @@ static void regulator_summary_show_subtree(struct seq_file *s,
class_for_each_device(&regulator_class, NULL, &summary_data,
regulator_summary_show_children);
}
struct summary_lock_data {
struct ww_acquire_ctx *ww_ctx;
struct regulator_dev **new_contended_rdev;
struct regulator_dev **old_contended_rdev;
};
static int regulator_summary_lock_one(struct device *dev, void *data)
{
struct regulator_dev *rdev = dev_to_rdev(dev);
struct summary_lock_data *lock_data = data;
int ret = 0;
if (rdev != *lock_data->old_contended_rdev) {
ret = regulator_lock_nested(rdev, lock_data->ww_ctx);
if (ret == -EDEADLK)
*lock_data->new_contended_rdev = rdev;
else
WARN_ON_ONCE(ret);
} else {
*lock_data->old_contended_rdev = NULL;
}
return ret;
}
static int regulator_summary_unlock_one(struct device *dev, void *data)
{
struct regulator_dev *rdev = dev_to_rdev(dev);
struct summary_lock_data *lock_data = data;
if (lock_data) {
if (rdev == *lock_data->new_contended_rdev)
return -EDEADLK;
}
regulator_unlock(rdev);
return 0;
}
static int regulator_summary_lock_all(struct ww_acquire_ctx *ww_ctx,
struct regulator_dev **new_contended_rdev,
struct regulator_dev **old_contended_rdev)
{
struct summary_lock_data lock_data;
int ret;
lock_data.ww_ctx = ww_ctx;
lock_data.new_contended_rdev = new_contended_rdev;
lock_data.old_contended_rdev = old_contended_rdev;
ret = class_for_each_device(&regulator_class, NULL, &lock_data,
regulator_summary_lock_one);
if (ret)
class_for_each_device(&regulator_class, NULL, &lock_data,
regulator_summary_unlock_one);
return ret;
}
static void regulator_summary_lock(struct ww_acquire_ctx *ww_ctx)
{
struct regulator_dev *new_contended_rdev = NULL;
struct regulator_dev *old_contended_rdev = NULL;
int err;
mutex_lock(&regulator_list_mutex);
ww_acquire_init(ww_ctx, &regulator_ww_class);
do {
if (new_contended_rdev) {
ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx);
old_contended_rdev = new_contended_rdev;
old_contended_rdev->ref_cnt++;
}
err = regulator_summary_lock_all(ww_ctx,
&new_contended_rdev,
&old_contended_rdev);
if (old_contended_rdev)
regulator_unlock(old_contended_rdev);
} while (err == -EDEADLK);
ww_acquire_done(ww_ctx);
}
static void regulator_summary_unlock(struct ww_acquire_ctx *ww_ctx)
{
class_for_each_device(&regulator_class, NULL, NULL,
regulator_summary_unlock_one);
ww_acquire_fini(ww_ctx);
mutex_unlock(&regulator_list_mutex);
}
static int regulator_summary_show_roots(struct device *dev, void *data)
......@@ -4782,12 +5361,18 @@ static int regulator_summary_show_roots(struct device *dev, void *data)
static int regulator_summary_show(struct seq_file *s, void *data)
{
struct ww_acquire_ctx ww_ctx;
seq_puts(s, " regulator use open bypass opmode voltage current min max\n");
seq_puts(s, "---------------------------------------------------------------------------------------\n");
regulator_summary_lock(&ww_ctx);
class_for_each_device(&regulator_class, NULL, s,
regulator_summary_show_roots);
regulator_summary_unlock(&ww_ctx);
return 0;
}
......@@ -4908,9 +5493,6 @@ static int __init regulator_init_complete(void)
class_for_each_device(&regulator_class, NULL, NULL,
regulator_late_cleanup);
class_for_each_device(&regulator_class, NULL, NULL,
regulator_register_fill_coupling_array);
return 0;
}
late_initcall_sync(regulator_init_complete);
......@@ -131,7 +131,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
if (error < 0)
goto error_i2c;
mutex_lock(&chip->rdev->mutex);
regulator_lock(chip->rdev);
if (val & DA9210_E_OVCURR) {
regulator_notifier_call_chain(chip->rdev,
......@@ -157,7 +157,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
handled |= DA9210_E_VMAX;
}
mutex_unlock(&chip->rdev->mutex);
regulator_unlock(chip->rdev);
if (handled) {
/* Clear handled events */
......
......@@ -171,6 +171,10 @@ static void of_get_regulation_constraints(struct device_node *np,
&pval))
constraints->max_spread = pval;
if (!of_property_read_u32(np, "regulator-max-step-microvolt",
&pval))
constraints->max_uV_step = pval;
constraints->over_current_protection = of_property_read_bool(np,
"regulator-over-current-protection");
......
......@@ -489,14 +489,14 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
mutex_lock(&rdev->mutex);
regulator_lock(rdev, NULL);
/* Send an overcurrent notification */
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_OVER_CURRENT,
NULL);
mutex_unlock(&rdev->mutex);
regulator_unlock(rdev);
return IRQ_HANDLED;
}
......
......@@ -1153,7 +1153,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
mutex_lock(&rdev->mutex);
regulator_lock(rdev);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
......@@ -1162,7 +1162,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
NULL);
mutex_unlock(&rdev->mutex);
regulator_unlock(rdev);
return IRQ_HANDLED;
}
......
......@@ -15,11 +15,12 @@
#ifndef __LINUX_REGULATOR_DRIVER_H_
#define __LINUX_REGULATOR_DRIVER_H_
#define MAX_COUPLED 4
#define MAX_COUPLED 2
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/regulator/consumer.h>
#include <linux/ww_mutex.h>
struct gpio_desc;
struct regmap;
......@@ -462,7 +463,7 @@ struct regulator_dev {
struct coupling_desc coupling_desc;
struct blocking_notifier_head notifier;
struct mutex mutex; /* consumer lock */
struct ww_mutex mutex; /* consumer lock */
struct task_struct *mutex_owner;
int ref_cnt;
struct module *owner;
......@@ -545,4 +546,7 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
bool enable);
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
void regulator_lock(struct regulator_dev *rdev);
void regulator_unlock(struct regulator_dev *rdev);
#endif
......@@ -158,6 +158,9 @@ struct regulation_constraints {
/* used for coupled regulators */
int max_spread;
/* used for changing voltage in steps */
int max_uV_step;
/* valid regulator operating modes for this machine */
unsigned int valid_modes_mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment