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

Commit 7a32b589 authored by MyungJoo Ham's avatar MyungJoo Ham Committed by Liam Girdwood
Browse files

Regulator: add suspend-finish API for regulator core.



The regulator core had suspend-prepare that turns off the regulators
when entering a system-wide suspend. However, it did not have
suspend-finish that pairs with suspend-prepare and the regulator core
has assumed that the regulator devices and their drivers support
autonomous recover at resume.

This patch adds regulator_suspend_finish that pairs with the
previously-existed regulator_suspend_prepare. The function
regulator_suspend_finish turns on the regulators that have always_on set
or positive use_count so that we can reset the regulator states
appropriately at resume.

In regulator_suspend_finish, if has_full_constraints, it disables
unnecessary regulators.

Signed-off-by: default avatarMyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Acked-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
--
Updates
v3
	comments corrected (Thanks to Igor)
v2
	disable unnecessary regulators (Thanks to Mark)
Signed-off-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
parent fb7c18ca
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -2655,6 +2655,47 @@ int regulator_suspend_prepare(suspend_state_t state)
}
EXPORT_SYMBOL_GPL(regulator_suspend_prepare);

/**
 * regulator_suspend_finish - resume regulators from system wide suspend
 *
 * Turn on regulators that might be turned off by regulator_suspend_prepare
 * and that should be turned on according to the regulators properties.
 */
int regulator_suspend_finish(void)
{
	struct regulator_dev *rdev;
	int ret = 0, error;

	mutex_lock(&regulator_list_mutex);
	list_for_each_entry(rdev, &regulator_list, list) {
		struct regulator_ops *ops = rdev->desc->ops;

		mutex_lock(&rdev->mutex);
		if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
				ops->enable) {
			error = ops->enable(rdev);
			if (error)
				ret = error;
		} else {
			if (!has_full_constraints)
				goto unlock;
			if (!ops->disable)
				goto unlock;
			if (ops->is_enabled && !ops->is_enabled(rdev))
				goto unlock;

			error = ops->disable(rdev);
			if (error)
				ret = error;
		}
unlock:
		mutex_unlock(&rdev->mutex);
	}
	mutex_unlock(&regulator_list_mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(regulator_suspend_finish);

/**
 * regulator_has_full_constraints - the system has fully specified constraints
 *
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ struct regulator_init_data {
};

int regulator_suspend_prepare(suspend_state_t state);
int regulator_suspend_finish(void);

#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void);