* @state: system suspend state
*
* Configure each regulator with it's suspend operating parameters for state.
- * This will usually be called by machine suspend code prior to supending.
*/
- int regulator_suspend_prepare(suspend_state_t state)
+ static int regulator_suspend_late(struct device *dev)
{
- /* ON is handled by regulator active state */
- if (state == PM_SUSPEND_ON)
- return -EINVAL;
+ suspend_state_t state = pm_suspend_target_state;
return class_for_each_device(®ulator_class, NULL, &state,
- _regulator_suspend_prepare);
+ _regulator_suspend_late);
}
- EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
-
- static int _regulator_suspend_finish(struct device *dev, void *data)
+ static int _regulator_resume_early(struct device *dev, void *data)
{
+ int ret = 0;
struct regulator_dev *rdev = dev_to_rdev(dev);
- int ret;
+ suspend_state_t *state = data;
+ struct regulator_state *rstate;
+
+ rstate = regulator_get_suspend_state(rdev, *state);
+ if (rstate == NULL)
+ return -EINVAL;
mutex_lock(&rdev->mutex);
- if (rdev->use_count > 0 || rdev->constraints->always_on) {
- if (!_regulator_is_enabled(rdev)) {
- ret = _regulator_do_enable(rdev);
- if (ret)
- dev_err(dev,
- "Failed to resume regulator %d\n",
- ret);
- }
- } else {
- if (!have_full_constraints())
- goto unlock;
- if (!_regulator_is_enabled(rdev))
- goto unlock;
- ret = _regulator_do_disable(rdev);
- if (ret)
- dev_err(dev, "Failed to suspend regulator %d\n", ret);
- }
- unlock:
+ if (rdev->desc->ops->resume_early &&
+ (rstate->enabled == ENABLE_IN_SUSPEND ||
+ rstate->enabled == DISABLE_IN_SUSPEND))
+ ret = rdev->desc->ops->resume_early(rdev);
+
mutex_unlock(&rdev->mutex);
- /* Keep processing regulators in spite of any errors */
- return 0;
+ return ret;
}
- /**
- * 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)
+ static int regulator_resume_early(struct device *dev)
{
- return class_for_each_device(®ulator_class, NULL, NULL,
- _regulator_suspend_finish);
+ suspend_state_t state = pm_suspend_target_state;
+
+ return class_for_each_device(®ulator_class, NULL, &state,
+ _regulator_resume_early);
}
- EXPORT_SYMBOL_GPL(regulator_suspend_finish);
-static struct class regulator_class = {
+ #else /* !CONFIG_SUSPEND */
+
+ #define regulator_suspend_late NULL
+ #define regulator_resume_early NULL
+
+ #endif /* !CONFIG_SUSPEND */
+
+ #ifdef CONFIG_PM
+ static const struct dev_pm_ops __maybe_unused regulator_pm_ops = {
+ .suspend_late = regulator_suspend_late,
+ .resume_early = regulator_resume_early,
+ };
+ #endif
+
++struct class regulator_class = {
+ .name = "regulator",
+ .dev_release = regulator_dev_release,
+ .dev_groups = regulator_dev_groups,
+ #ifdef CONFIG_PM
+ .pm = ®ulator_pm_ops,
+ #endif
+ };
/**
* regulator_has_full_constraints - the system has fully specified constraints
*