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: ...@@ -82,6 +82,8 @@ Optional properties:
- regulator-coupled-max-spread: Array of maximum spread between voltages of - regulator-coupled-max-spread: Array of maximum spread between voltages of
coupled regulators in microvolts, each value in the array relates to the coupled regulators in microvolts, each value in the array relates to the
corresponding couple specified by the regulator-coupled-with property. 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: Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple - regulator-compatible: If a regulator chip contains multiple
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
#define rdev_dbg(rdev, fmt, ...) \ #define rdev_dbg(rdev, fmt, ...) \
pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) 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 DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_map_list); static LIST_HEAD(regulator_map_list);
static LIST_HEAD(regulator_ena_gpio_list); static LIST_HEAD(regulator_ena_gpio_list);
...@@ -105,6 +107,11 @@ static int _notifier_call_chain(struct regulator_dev *rdev, ...@@ -105,6 +107,11 @@ static int _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data); unsigned long event, void *data);
static int _regulator_do_set_voltage(struct regulator_dev *rdev, static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV); 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, static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev, struct device *dev,
const char *supply_name); const char *supply_name);
...@@ -149,7 +156,7 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev) ...@@ -149,7 +156,7 @@ static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
/** /**
* regulator_lock_nested - lock a single regulator * regulator_lock_nested - lock a single regulator
* @rdev: regulator source * @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 * This function can be called many times by one task on
* a single regulator and its mutex will be locked only * 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) ...@@ -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 * than the one, which initially locked the mutex, it will
* wait on mutex. * wait on mutex.
*/ */
static void regulator_lock_nested(struct regulator_dev *rdev, static inline int regulator_lock_nested(struct regulator_dev *rdev,
unsigned int subclass) struct ww_acquire_ctx *ww_ctx)
{ {
if (!mutex_trylock(&rdev->mutex)) { bool lock = false;
if (rdev->mutex_owner == current) { int ret = 0;
mutex_lock(&regulator_nesting_mutex);
if (ww_ctx || !ww_mutex_trylock(&rdev->mutex)) {
if (rdev->mutex_owner == current)
rdev->ref_cnt++; 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; if (lock && ret != -EDEADLK) {
rdev->mutex_owner = current; 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) ...@@ -184,47 +219,159 @@ static inline void regulator_lock(struct regulator_dev *rdev)
* This function unlocks the mutex when the * This function unlocks the mutex when the
* reference counter reaches 0. * 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) { struct regulator_dev *c_rdev;
rdev->ref_cnt--; int i;
for (i = 1; i < rdev->coupling_desc.n_coupled; i++) {
c_rdev = rdev->coupling_desc.coupled_rdevs[i];
if (!rdev->ref_cnt) { if (rdev->supply->rdev == c_rdev)
rdev->mutex_owner = NULL; return true;
mutex_unlock(&rdev->mutex); }
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 * regulator_unlock_dependent - unlock regulator's suppliers and coupled
* @rdev: regulator source * 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; regulator_unlock_recursive(rdev, rdev->coupling_desc.n_coupled);
ww_acquire_fini(ww_ctx);
for (i = 0; rdev; rdev = rdev_get_supply(rdev), i++)
regulator_lock_nested(rdev, i);
} }
/** /**
* regulator_unlock_supply - unlock a regulator and its supplies * regulator_lock_dependent - lock regulator's suppliers and coupled regulators
* @rdev: regulator source * @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) { mutex_lock(&regulator_list_mutex);
regulator_unlock(rdev);
supply = rdev->supply;
if (!rdev->supply) ww_acquire_init(ww_ctx, &regulator_ww_class);
return;
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) ...@@ -773,7 +920,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
int current_uA = 0, output_uV, input_uV, err; int current_uA = 0, output_uV, input_uV, err;
unsigned int mode; 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 * 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, ...@@ -1748,6 +1895,16 @@ struct regulator *_regulator_get(struct device *dev, const char *id,
return regulator; 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); ret = regulator_resolve_supply(rdev);
if (ret < 0) { if (ret < 0) {
regulator = ERR_PTR(ret); regulator = ERR_PTR(ret);
...@@ -2265,7 +2422,20 @@ static int _regulator_enable(struct regulator_dev *rdev) ...@@ -2265,7 +2422,20 @@ static int _regulator_enable(struct regulator_dev *rdev)
{ {
int ret; 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 */ /* check voltage and requested load before enabling */
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS)) if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
...@@ -2276,18 +2446,20 @@ static int _regulator_enable(struct regulator_dev *rdev) ...@@ -2276,18 +2446,20 @@ static int _regulator_enable(struct regulator_dev *rdev)
ret = _regulator_is_enabled(rdev); ret = _regulator_is_enabled(rdev);
if (ret == -EINVAL || ret == 0) { if (ret == -EINVAL || ret == 0) {
if (!regulator_ops_is_valid(rdev, if (!regulator_ops_is_valid(rdev,
REGULATOR_CHANGE_STATUS)) REGULATOR_CHANGE_STATUS)) {
return -EPERM; ret = -EPERM;
goto err_disable_supply;
}
ret = _regulator_do_enable(rdev); ret = _regulator_do_enable(rdev);
if (ret < 0) if (ret < 0)
return ret; goto err_disable_supply;
_notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE,
NULL); NULL);
} else if (ret < 0) { } else if (ret < 0) {
rdev_err(rdev, "is_enabled() failed: %d\n", ret); rdev_err(rdev, "is_enabled() failed: %d\n", ret);
return ret; goto err_disable_supply;
} }
/* Fallthrough on positive return values - already enabled */ /* Fallthrough on positive return values - already enabled */
} }
...@@ -2295,6 +2467,12 @@ static int _regulator_enable(struct regulator_dev *rdev) ...@@ -2295,6 +2467,12 @@ static int _regulator_enable(struct regulator_dev *rdev)
rdev->use_count++; rdev->use_count++;
return 0; 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) ...@@ -2311,23 +2489,15 @@ static int _regulator_enable(struct regulator_dev *rdev)
int regulator_enable(struct regulator *regulator) int regulator_enable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret = 0; int ret = 0;
if (regulator->always_on) if (regulator->always_on)
return 0; return 0;
if (rdev->supply) { regulator_lock_dependent(rdev, &ww_ctx);
ret = regulator_enable(rdev->supply);
if (ret != 0)
return ret;
}
mutex_lock(&rdev->mutex);
ret = _regulator_enable(rdev); ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex); regulator_unlock_dependent(rdev, &ww_ctx);
if (ret != 0 && rdev->supply)
regulator_disable(rdev->supply);
return ret; return ret;
} }
...@@ -2369,7 +2539,7 @@ static int _regulator_disable(struct regulator_dev *rdev) ...@@ -2369,7 +2539,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
{ {
int ret = 0; int ret = 0;
lockdep_assert_held_once(&rdev->mutex); lockdep_assert_held_once(&rdev->mutex.base);
if (WARN(rdev->use_count <= 0, if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n", rdev_get_name(rdev))) "unbalanced disables for %s\n", rdev_get_name(rdev)))
...@@ -2407,6 +2577,12 @@ static int _regulator_disable(struct regulator_dev *rdev) ...@@ -2407,6 +2577,12 @@ static int _regulator_disable(struct regulator_dev *rdev)
rdev->use_count--; 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; return ret;
} }
...@@ -2425,17 +2601,15 @@ static int _regulator_disable(struct regulator_dev *rdev) ...@@ -2425,17 +2601,15 @@ static int _regulator_disable(struct regulator_dev *rdev)
int regulator_disable(struct regulator *regulator) int regulator_disable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret = 0; int ret = 0;
if (regulator->always_on) if (regulator->always_on)
return 0; return 0;
mutex_lock(&rdev->mutex); regulator_lock_dependent(rdev, &ww_ctx);
ret = _regulator_disable(rdev); ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex); regulator_unlock_dependent(rdev, &ww_ctx);
if (ret == 0 && rdev->supply)
regulator_disable(rdev->supply);
return ret; return ret;
} }
...@@ -2446,7 +2620,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev) ...@@ -2446,7 +2620,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{ {
int ret = 0; 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 | ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_PRE_DISABLE, NULL); REGULATOR_EVENT_PRE_DISABLE, NULL);
...@@ -2479,12 +2653,15 @@ static int _regulator_force_disable(struct regulator_dev *rdev) ...@@ -2479,12 +2653,15 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
int regulator_force_disable(struct regulator *regulator) int regulator_force_disable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev; struct regulator_dev *rdev = regulator->rdev;
struct ww_acquire_ctx ww_ctx;
int ret; int ret;
mutex_lock(&rdev->mutex); regulator_lock_dependent(rdev, &ww_ctx);
regulator->uA_load = 0; regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev); 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) if (rdev->supply)
while (rdev->open_count--) while (rdev->open_count--)
...@@ -2498,9 +2675,10 @@ static void regulator_disable_work(struct work_struct *work) ...@@ -2498,9 +2675,10 @@ static void regulator_disable_work(struct work_struct *work)
{ {
struct regulator_dev *rdev = container_of(work, struct regulator_dev, struct regulator_dev *rdev = container_of(work, struct regulator_dev,
disable_work.work); disable_work.work);
struct ww_acquire_ctx ww_ctx;
int count, i, ret; int count, i, ret;
regulator_lock(rdev); regulator_lock_dependent(rdev, &ww_ctx);
BUG_ON(!rdev->deferred_disables); BUG_ON(!rdev->deferred_disables);
...@@ -2521,7 +2699,10 @@ static void regulator_disable_work(struct work_struct *work) ...@@ -2521,7 +2699,10 @@ static void regulator_disable_work(struct work_struct *work)
rdev_err(rdev, "Deferred disable failed: %d\n", ret); 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) { if (rdev->supply) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -2632,9 +2813,9 @@ int regulator_is_enabled(struct regulator *regulator) ...@@ -2632,9 +2813,9 @@ int regulator_is_enabled(struct regulator *regulator)
if (regulator->always_on) if (regulator->always_on)
return 1; return 1;
mutex_lock(&regulator->rdev->mutex); regulator_lock(regulator->rdev);
ret = _regulator_is_enabled(regulator->rdev); ret = _regulator_is_enabled(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex); regulator_unlock(regulator->rdev);
return ret; return ret;
} }
...@@ -3048,8 +3229,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3048,8 +3229,6 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
int ret = 0; int ret = 0;
int old_min_uV, old_max_uV; int old_min_uV, old_max_uV;
int current_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 /* If we're setting the same range as last time the change
* should be a noop (some cpufreq implementations use the same * should be a noop (some cpufreq implementations use the same
...@@ -3089,10 +3268,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3089,10 +3268,27 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
voltage->min_uV = min_uV; voltage->min_uV = min_uV;
voltage->max_uV = max_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) if (ret < 0)
goto out2; 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 && if (rdev->supply &&
regulator_ops_is_valid(rdev->supply->rdev, regulator_ops_is_valid(rdev->supply->rdev,
REGULATOR_CHANGE_VOLTAGE) && REGULATOR_CHANGE_VOLTAGE) &&
...@@ -3104,13 +3300,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3104,13 +3300,13 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
selector = regulator_map_voltage(rdev, min_uV, max_uV); selector = regulator_map_voltage(rdev, min_uV, max_uV);
if (selector < 0) { if (selector < 0) {
ret = selector; ret = selector;
goto out2; goto out;
} }
best_supply_uV = _regulator_list_voltage(rdev, selector, 0); best_supply_uV = _regulator_list_voltage(rdev, selector, 0);
if (best_supply_uV < 0) { if (best_supply_uV < 0) {
ret = best_supply_uV; ret = best_supply_uV;
goto out2; goto out;
} }
best_supply_uV += rdev->desc->min_dropout_uV; best_supply_uV += rdev->desc->min_dropout_uV;
...@@ -3118,7 +3314,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3118,7 +3314,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
current_supply_uV = _regulator_get_voltage(rdev->supply->rdev); current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);
if (current_supply_uV < 0) { if (current_supply_uV < 0) {
ret = current_supply_uV; ret = current_supply_uV;
goto out2; goto out;
} }
supply_change_uV = best_supply_uV - current_supply_uV; supply_change_uV = best_supply_uV - current_supply_uV;
...@@ -3130,7 +3326,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3130,7 +3326,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
if (ret) { if (ret) {
dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
ret); ret);
goto out2; goto out;
} }
} }
...@@ -3140,7 +3336,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3140,7 +3336,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
ret = _regulator_do_set_suspend_voltage(rdev, min_uV, ret = _regulator_do_set_suspend_voltage(rdev, min_uV,
max_uV, state); max_uV, state);
if (ret < 0) if (ret < 0)
goto out2; goto out;
if (supply_change_uV < 0) { if (supply_change_uV < 0) {
ret = regulator_set_voltage_unlocked(rdev->supply, ret = regulator_set_voltage_unlocked(rdev->supply,
...@@ -3154,10 +3350,273 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -3154,10 +3350,273 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
out: out:
return ret; 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; return ret;
} }
...@@ -3181,14 +3640,15 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, ...@@ -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 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, ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV,
PM_SUSPEND_ON); PM_SUSPEND_ON);
regulator_unlock_supply(regulator->rdev); regulator_unlock_dependent(regulator->rdev, &ww_ctx);
return ret; return ret;
} }
...@@ -3260,18 +3720,19 @@ static int _regulator_set_suspend_voltage(struct regulator *regulator, ...@@ -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 regulator_set_suspend_voltage(struct regulator *regulator, int min_uV,
int max_uV, suspend_state_t state) 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() */ /* PM_SUSPEND_ON is handled by regulator_set_voltage() */
if (regulator_check_states(state) || state == PM_SUSPEND_ON) if (regulator_check_states(state) || state == PM_SUSPEND_ON)
return -EINVAL; return -EINVAL;
regulator_lock_supply(regulator->rdev); regulator_lock_dependent(regulator->rdev, &ww_ctx);
ret = _regulator_set_suspend_voltage(regulator, min_uV, ret = _regulator_set_suspend_voltage(regulator, min_uV,
max_uV, state); max_uV, state);
regulator_unlock_supply(regulator->rdev); regulator_unlock_dependent(regulator->rdev, &ww_ctx);
return ret; return ret;
} }
...@@ -3461,13 +3922,12 @@ static int _regulator_get_voltage(struct regulator_dev *rdev) ...@@ -3461,13 +3922,12 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
*/ */
int regulator_get_voltage(struct regulator *regulator) int regulator_get_voltage(struct regulator *regulator)
{ {
struct ww_acquire_ctx ww_ctx;
int ret; int ret;
regulator_lock_supply(regulator->rdev); regulator_lock_dependent(regulator->rdev, &ww_ctx);
ret = _regulator_get_voltage(regulator->rdev); ret = _regulator_get_voltage(regulator->rdev);
regulator_unlock_dependent(regulator->rdev, &ww_ctx);
regulator_unlock_supply(regulator->rdev);
return ret; return ret;
} }
...@@ -4003,7 +4463,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); ...@@ -4003,7 +4463,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
int regulator_notifier_call_chain(struct regulator_dev *rdev, int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data) unsigned long event, void *data)
{ {
lockdep_assert_held_once(&rdev->mutex); lockdep_assert_held_once(&rdev->mutex.base);
_notifier_call_chain(rdev, event, data); _notifier_call_chain(rdev, event, data);
return NOTIFY_DONE; return NOTIFY_DONE;
...@@ -4192,7 +4652,7 @@ static int regulator_register_resolve_supply(struct device *dev, void *data) ...@@ -4192,7 +4652,7 @@ static int regulator_register_resolve_supply(struct device *dev, void *data)
return 0; 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; struct coupling_desc *c_desc = &rdev->coupling_desc;
int n_coupled = c_desc->n_coupled; int n_coupled = c_desc->n_coupled;
...@@ -4206,33 +4666,58 @@ static int regulator_fill_coupling_array(struct regulator_dev *rdev) ...@@ -4206,33 +4666,58 @@ static int regulator_fill_coupling_array(struct regulator_dev *rdev)
c_rdev = of_parse_coupled_regulator(rdev, i - 1); c_rdev = of_parse_coupled_regulator(rdev, i - 1);
if (c_rdev) { if (!c_rdev)
c_desc->coupled_rdevs[i] = c_rdev; continue;
c_desc->n_resolved++;
}
}
if (rdev->coupling_desc.n_resolved < n_coupled) regulator_lock(c_rdev);
return -1;
else c_desc->coupled_rdevs[i] = c_rdev;
return 0; c_desc->n_resolved++;
regulator_unlock(c_rdev);
regulator_resolve_coupling(c_rdev);
}
} }
static int regulator_register_fill_coupling_array(struct device *dev, static void regulator_remove_coupling(struct regulator_dev *rdev)
void *data)
{ {
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)) n_coupled = c_desc->n_coupled;
return 0;
if (regulator_fill_coupling_array(rdev)) for (i = 1; i < n_coupled; i++) {
rdev_dbg(rdev, "unable to resolve coupling\n"); 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; int n_phandles;
...@@ -4272,13 +4757,6 @@ static int regulator_resolve_coupling(struct regulator_dev *rdev) ...@@ -4272,13 +4757,6 @@ static int regulator_resolve_coupling(struct regulator_dev *rdev)
if (!of_check_coupling_data(rdev)) if (!of_check_coupling_data(rdev))
return -EPERM; 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; return 0;
} }
...@@ -4353,7 +4831,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -4353,7 +4831,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev->dev.of_node = of_node_get(config->of_node); 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->reg_data = config->driver_data;
rdev->owner = regulator_desc->owner; rdev->owner = regulator_desc->owner;
rdev->desc = regulator_desc; rdev->desc = regulator_desc;
...@@ -4415,11 +4893,8 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -4415,11 +4893,8 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0) if (ret < 0)
goto wash; goto wash;
mutex_lock(&regulator_list_mutex); ret = regulator_init_coupling(rdev);
ret = regulator_resolve_coupling(rdev); if (ret < 0)
mutex_unlock(&regulator_list_mutex);
if (ret != 0)
goto wash; goto wash;
/* add consumers devices */ /* add consumers devices */
...@@ -4453,6 +4928,11 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -4453,6 +4928,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev_init_debugfs(rdev); 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 */ /* try to resolve regulators supply since a new one was registered */
class_for_each_device(&regulator_class, NULL, NULL, class_for_each_device(&regulator_class, NULL, NULL,
regulator_register_resolve_supply); regulator_register_resolve_supply);
...@@ -4491,15 +4971,19 @@ void regulator_unregister(struct regulator_dev *rdev) ...@@ -4491,15 +4971,19 @@ void regulator_unregister(struct regulator_dev *rdev)
regulator_disable(rdev->supply); regulator_disable(rdev->supply);
regulator_put(rdev->supply); regulator_put(rdev->supply);
} }
mutex_lock(&regulator_list_mutex); mutex_lock(&regulator_list_mutex);
debugfs_remove_recursive(rdev->debugfs); debugfs_remove_recursive(rdev->debugfs);
flush_work(&rdev->disable_work.work); flush_work(&rdev->disable_work.work);
WARN_ON(rdev->open_count); WARN_ON(rdev->open_count);
regulator_remove_coupling(rdev);
unset_regulator_supplies(rdev); unset_regulator_supplies(rdev);
list_del(&rdev->list); list_del(&rdev->list);
regulator_ena_gpio_free(rdev); regulator_ena_gpio_free(rdev);
mutex_unlock(&regulator_list_mutex);
device_unregister(&rdev->dev); device_unregister(&rdev->dev);
mutex_unlock(&regulator_list_mutex);
} }
EXPORT_SYMBOL_GPL(regulator_unregister); EXPORT_SYMBOL_GPL(regulator_unregister);
...@@ -4707,8 +5191,6 @@ static void regulator_summary_show_subtree(struct seq_file *s, ...@@ -4707,8 +5191,6 @@ static void regulator_summary_show_subtree(struct seq_file *s,
if (!rdev) if (!rdev)
return; return;
regulator_lock_nested(rdev, level);
opmode = _regulator_get_mode_unlocked(rdev); opmode = _regulator_get_mode_unlocked(rdev);
seq_printf(s, "%*s%-*s %3d %4d %6d %7s ", seq_printf(s, "%*s%-*s %3d %4d %6d %7s ",
level * 3 + 1, "", level * 3 + 1, "",
...@@ -4765,8 +5247,105 @@ static void regulator_summary_show_subtree(struct seq_file *s, ...@@ -4765,8 +5247,105 @@ static void regulator_summary_show_subtree(struct seq_file *s,
class_for_each_device(&regulator_class, NULL, &summary_data, class_for_each_device(&regulator_class, NULL, &summary_data,
regulator_summary_show_children); 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); 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) 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) ...@@ -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) 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, " regulator use open bypass opmode voltage current min max\n");
seq_puts(s, "---------------------------------------------------------------------------------------\n"); seq_puts(s, "---------------------------------------------------------------------------------------\n");
regulator_summary_lock(&ww_ctx);
class_for_each_device(&regulator_class, NULL, s, class_for_each_device(&regulator_class, NULL, s,
regulator_summary_show_roots); regulator_summary_show_roots);
regulator_summary_unlock(&ww_ctx);
return 0; return 0;
} }
...@@ -4908,9 +5493,6 @@ static int __init regulator_init_complete(void) ...@@ -4908,9 +5493,6 @@ static int __init regulator_init_complete(void)
class_for_each_device(&regulator_class, NULL, NULL, class_for_each_device(&regulator_class, NULL, NULL,
regulator_late_cleanup); regulator_late_cleanup);
class_for_each_device(&regulator_class, NULL, NULL,
regulator_register_fill_coupling_array);
return 0; return 0;
} }
late_initcall_sync(regulator_init_complete); late_initcall_sync(regulator_init_complete);
...@@ -131,7 +131,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data) ...@@ -131,7 +131,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
if (error < 0) if (error < 0)
goto error_i2c; goto error_i2c;
mutex_lock(&chip->rdev->mutex); regulator_lock(chip->rdev);
if (val & DA9210_E_OVCURR) { if (val & DA9210_E_OVCURR) {
regulator_notifier_call_chain(chip->rdev, regulator_notifier_call_chain(chip->rdev,
...@@ -157,7 +157,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data) ...@@ -157,7 +157,7 @@ static irqreturn_t da9210_irq_handler(int irq, void *data)
handled |= DA9210_E_VMAX; handled |= DA9210_E_VMAX;
} }
mutex_unlock(&chip->rdev->mutex); regulator_unlock(chip->rdev);
if (handled) { if (handled) {
/* Clear handled events */ /* Clear handled events */
......
...@@ -171,6 +171,10 @@ static void of_get_regulation_constraints(struct device_node *np, ...@@ -171,6 +171,10 @@ static void of_get_regulation_constraints(struct device_node *np,
&pval)) &pval))
constraints->max_spread = 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, constraints->over_current_protection = of_property_read_bool(np,
"regulator-over-current-protection"); "regulator-over-current-protection");
......
...@@ -489,14 +489,14 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data) ...@@ -489,14 +489,14 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data)
{ {
struct regulator_dev *rdev = (struct regulator_dev *)data; struct regulator_dev *rdev = (struct regulator_dev *)data;
mutex_lock(&rdev->mutex); regulator_lock(rdev, NULL);
/* Send an overcurrent notification */ /* Send an overcurrent notification */
regulator_notifier_call_chain(rdev, regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_OVER_CURRENT, REGULATOR_EVENT_OVER_CURRENT,
NULL); NULL);
mutex_unlock(&rdev->mutex); regulator_unlock(rdev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -1153,7 +1153,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data) ...@@ -1153,7 +1153,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
{ {
struct regulator_dev *rdev = (struct regulator_dev *)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) if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev, regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT, REGULATOR_EVENT_REGULATION_OUT,
...@@ -1162,7 +1162,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data) ...@@ -1162,7 +1162,7 @@ static irqreturn_t pmic_uv_handler(int irq, void *data)
regulator_notifier_call_chain(rdev, regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE, REGULATOR_EVENT_UNDER_VOLTAGE,
NULL); NULL);
mutex_unlock(&rdev->mutex); regulator_unlock(rdev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
#ifndef __LINUX_REGULATOR_DRIVER_H_ #ifndef __LINUX_REGULATOR_DRIVER_H_
#define __LINUX_REGULATOR_DRIVER_H_ #define __LINUX_REGULATOR_DRIVER_H_
#define MAX_COUPLED 4 #define MAX_COUPLED 2
#include <linux/device.h> #include <linux/device.h>
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/ww_mutex.h>
struct gpio_desc; struct gpio_desc;
struct regmap; struct regmap;
...@@ -462,7 +463,7 @@ struct regulator_dev { ...@@ -462,7 +463,7 @@ struct regulator_dev {
struct coupling_desc coupling_desc; struct coupling_desc coupling_desc;
struct blocking_notifier_head notifier; struct blocking_notifier_head notifier;
struct mutex mutex; /* consumer lock */ struct ww_mutex mutex; /* consumer lock */
struct task_struct *mutex_owner; struct task_struct *mutex_owner;
int ref_cnt; int ref_cnt;
struct module *owner; struct module *owner;
...@@ -545,4 +546,7 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev, ...@@ -545,4 +546,7 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
bool enable); bool enable);
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); 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 #endif
...@@ -158,6 +158,9 @@ struct regulation_constraints { ...@@ -158,6 +158,9 @@ struct regulation_constraints {
/* used for coupled regulators */ /* used for coupled regulators */
int max_spread; int max_spread;
/* used for changing voltage in steps */
int max_uV_step;
/* valid regulator operating modes for this machine */ /* valid regulator operating modes for this machine */
unsigned int valid_modes_mask; 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