Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 7e4d9683 authored by Douglas Anderson's avatar Douglas Anderson Committed by Mark Brown
Browse files

regulator: core: Add locking to debugfs regulator_summary



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: default avatarDouglas Anderson <dianders@chromium.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7d3827b5
Loading
Loading
Loading
Loading
+31 −20
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
}

@@ -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) {
@@ -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)