Skip to content

Commit

Permalink
regulator: core: Add locking to debugfs regulator_summary
Browse files Browse the repository at this point in the history
Most functions that access the rdev lock the rdev mutex before looking
at data.  ...but not the code that implements the debugfs
regulator_summary.  It probably should though, so let's do it.

Note: this fixes no known issues.  The problem was found only by code
inspection.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Douglas Anderson authored and Mark Brown committed Aug 28, 2018
1 parent 7d3827b commit 7e4d968
Showing 1 changed file with 31 additions and 20 deletions.
51 changes: 31 additions & 20 deletions drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3475,21 +3475,23 @@ int regulator_set_current_limit(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_set_current_limit);

static int _regulator_get_current_limit_unlocked(struct regulator_dev *rdev)
{
/* sanity check */
if (!rdev->desc->ops->get_current_limit)
return -EINVAL;

return rdev->desc->ops->get_current_limit(rdev);
}

static int _regulator_get_current_limit(struct regulator_dev *rdev)
{
int ret;

regulator_lock(rdev);

/* sanity check */
if (!rdev->desc->ops->get_current_limit) {
ret = -EINVAL;
goto out;
}

ret = rdev->desc->ops->get_current_limit(rdev);
out:
ret = _regulator_get_current_limit_unlocked(rdev);
regulator_unlock(rdev);

return ret;
}

Expand Down Expand Up @@ -3554,21 +3556,23 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
}
EXPORT_SYMBOL_GPL(regulator_set_mode);

static unsigned int _regulator_get_mode_unlocked(struct regulator_dev *rdev)
{
/* sanity check */
if (!rdev->desc->ops->get_mode)
return -EINVAL;

return rdev->desc->ops->get_mode(rdev);
}

static unsigned int _regulator_get_mode(struct regulator_dev *rdev)
{
int ret;

regulator_lock(rdev);

/* sanity check */
if (!rdev->desc->ops->get_mode) {
ret = -EINVAL;
goto out;
}

ret = rdev->desc->ops->get_mode(rdev);
out:
ret = _regulator_get_mode_unlocked(rdev);
regulator_unlock(rdev);

return ret;
}

Expand Down Expand Up @@ -4675,18 +4679,23 @@ static void regulator_summary_show_subtree(struct seq_file *s,
struct regulation_constraints *c;
struct regulator *consumer;
struct summary_data summary_data;
unsigned int opmode;

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, "",
30 - level * 3, rdev_get_name(rdev),
rdev->use_count, rdev->open_count, rdev->bypass_count,
regulator_opmode_to_str(_regulator_get_mode(rdev)));
regulator_opmode_to_str(opmode));

seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000);
seq_printf(s, "%5dmA ", _regulator_get_current_limit(rdev) / 1000);
seq_printf(s, "%5dmA ",
_regulator_get_current_limit_unlocked(rdev) / 1000);

c = rdev->constraints;
if (c) {
Expand Down Expand Up @@ -4733,6 +4742,8 @@ static void regulator_summary_show_subtree(struct seq_file *s,

class_for_each_device(&regulator_class, NULL, &summary_data,
regulator_summary_show_children);

regulator_unlock(rdev);
}

static int regulator_summary_show_roots(struct device *dev, void *data)
Expand Down

0 comments on commit 7e4d968

Please sign in to comment.