mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-04 02:25:58 +00:00
regulator: Allow regulators to verify enabled during enable()
Some regulators might need to verify that they have indeed been enabled after the enable() call is made and enable_time delay has passed. This is implemented by repeatedly checking is_enabled() upto poll_enabled_time, waiting for the already calculated enable delay in each iteration. Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org> Link: https://lore.kernel.org/r/20200622124110.20971-2-sumit.semwal@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
308e65ad06
commit
f7d7ad42a9
@ -2347,6 +2347,37 @@ static void _regulator_enable_delay(unsigned int delay)
|
|||||||
udelay(us);
|
udelay(us);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _regulator_check_status_enabled
|
||||||
|
*
|
||||||
|
* A helper function to check if the regulator status can be interpreted
|
||||||
|
* as 'regulator is enabled'.
|
||||||
|
* @rdev: the regulator device to check
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* * 1 - if status shows regulator is in enabled state
|
||||||
|
* * 0 - if not enabled state
|
||||||
|
* * Error Value - as received from ops->get_status()
|
||||||
|
*/
|
||||||
|
static inline int _regulator_check_status_enabled(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
int ret = rdev->desc->ops->get_status(rdev);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
rdev_info(rdev, "get_status returned error: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case REGULATOR_STATUS_OFF:
|
||||||
|
case REGULATOR_STATUS_ERROR:
|
||||||
|
case REGULATOR_STATUS_UNDEFINED:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int _regulator_do_enable(struct regulator_dev *rdev)
|
static int _regulator_do_enable(struct regulator_dev *rdev)
|
||||||
{
|
{
|
||||||
int ret, delay;
|
int ret, delay;
|
||||||
@ -2407,7 +2438,37 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
|
|||||||
* together. */
|
* together. */
|
||||||
trace_regulator_enable_delay(rdev_get_name(rdev));
|
trace_regulator_enable_delay(rdev_get_name(rdev));
|
||||||
|
|
||||||
_regulator_enable_delay(delay);
|
/* If poll_enabled_time is set, poll upto the delay calculated
|
||||||
|
* above, delaying poll_enabled_time uS to check if the regulator
|
||||||
|
* actually got enabled.
|
||||||
|
* If the regulator isn't enabled after enable_delay has
|
||||||
|
* expired, return -ETIMEDOUT.
|
||||||
|
*/
|
||||||
|
if (rdev->desc->poll_enabled_time) {
|
||||||
|
unsigned int time_remaining = delay;
|
||||||
|
|
||||||
|
while (time_remaining > 0) {
|
||||||
|
_regulator_enable_delay(rdev->desc->poll_enabled_time);
|
||||||
|
|
||||||
|
if (rdev->desc->ops->get_status) {
|
||||||
|
ret = _regulator_check_status_enabled(rdev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
else if (ret)
|
||||||
|
break;
|
||||||
|
} else if (rdev->desc->ops->is_enabled(rdev))
|
||||||
|
break;
|
||||||
|
|
||||||
|
time_remaining -= rdev->desc->poll_enabled_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_remaining <= 0) {
|
||||||
|
rdev_err(rdev, "Enabled check timed out\n");
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_regulator_enable_delay(delay);
|
||||||
|
}
|
||||||
|
|
||||||
trace_regulator_enable_complete(rdev_get_name(rdev));
|
trace_regulator_enable_complete(rdev_get_name(rdev));
|
||||||
|
|
||||||
|
@ -305,6 +305,9 @@ enum regulator_type {
|
|||||||
* @enable_time: Time taken for initial enable of regulator (in uS).
|
* @enable_time: Time taken for initial enable of regulator (in uS).
|
||||||
* @off_on_delay: guard time (in uS), before re-enabling a regulator
|
* @off_on_delay: guard time (in uS), before re-enabling a regulator
|
||||||
*
|
*
|
||||||
|
* @poll_enabled_time: The polling interval (in uS) to use while checking that
|
||||||
|
* the regulator was actually enabled. Max upto enable_time.
|
||||||
|
*
|
||||||
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
|
* @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode
|
||||||
*/
|
*/
|
||||||
struct regulator_desc {
|
struct regulator_desc {
|
||||||
@ -372,6 +375,8 @@ struct regulator_desc {
|
|||||||
|
|
||||||
unsigned int off_on_delay;
|
unsigned int off_on_delay;
|
||||||
|
|
||||||
|
unsigned int poll_enabled_time;
|
||||||
|
|
||||||
unsigned int (*of_map_mode)(unsigned int mode);
|
unsigned int (*of_map_mode)(unsigned int mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user