mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-06 10:57:46 +00:00
Merge remote-tracking branch 'regulator/topic/core' into regulator-next
This commit is contained in:
commit
81e439f476
4 changed files with 83 additions and 6 deletions
|
@ -14,6 +14,11 @@ Optional properties:
|
|||
- regulator-ramp-delay: ramp delay for regulator(in uV/uS)
|
||||
For hardwares which support disabling ramp rate, it should be explicitly
|
||||
intialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
|
||||
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
|
||||
rail to reach the target voltage, plus/minus whatever tolerance the board
|
||||
design requires. This property describes the total system ramp time
|
||||
required due to the combination of internal ramping of the regulator itself,
|
||||
and board design issues such as trace capacitance and load on the supply.
|
||||
|
||||
Deprecated properties:
|
||||
- regulator-compatible: If a regulator chip contains multiple
|
||||
|
|
|
@ -919,6 +919,36 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int machine_constraints_current(struct regulator_dev *rdev,
|
||||
struct regulation_constraints *constraints)
|
||||
{
|
||||
struct regulator_ops *ops = rdev->desc->ops;
|
||||
int ret;
|
||||
|
||||
if (!constraints->min_uA && !constraints->max_uA)
|
||||
return 0;
|
||||
|
||||
if (constraints->min_uA > constraints->max_uA) {
|
||||
rdev_err(rdev, "Invalid current constraints\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ops->set_current_limit || !ops->get_current_limit) {
|
||||
rdev_warn(rdev, "Operation of current configuration missing\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set regulator current in constraints range */
|
||||
ret = ops->set_current_limit(rdev, constraints->min_uA,
|
||||
constraints->max_uA);
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "Failed to set current constraint, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* set_machine_constraints - sets regulator constraints
|
||||
* @rdev: regulator source
|
||||
|
@ -949,6 +979,10 @@ static int set_machine_constraints(struct regulator_dev *rdev,
|
|||
if (ret != 0)
|
||||
goto out;
|
||||
|
||||
ret = machine_constraints_current(rdev, rdev->constraints);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
|
||||
/* do we need to setup our suspend state */
|
||||
if (rdev->constraints->initial_state) {
|
||||
ret = suspend_prepare(rdev, rdev->constraints->initial_state);
|
||||
|
@ -1182,6 +1216,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
|||
|
||||
static int _regulator_get_enable_time(struct regulator_dev *rdev)
|
||||
{
|
||||
if (rdev->constraints && rdev->constraints->enable_time)
|
||||
return rdev->constraints->enable_time;
|
||||
if (!rdev->desc->ops->enable_time)
|
||||
return rdev->desc->enable_time;
|
||||
return rdev->desc->ops->enable_time(rdev);
|
||||
|
@ -1276,7 +1312,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
|
|||
|
||||
if (id == NULL) {
|
||||
pr_err("get() with no identifier\n");
|
||||
return regulator;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (dev)
|
||||
|
@ -1733,11 +1769,39 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
|
|||
* together. */
|
||||
trace_regulator_enable_delay(rdev_get_name(rdev));
|
||||
|
||||
if (delay >= 1000) {
|
||||
mdelay(delay / 1000);
|
||||
udelay(delay % 1000);
|
||||
} else if (delay) {
|
||||
udelay(delay);
|
||||
/*
|
||||
* Delay for the requested amount of time as per the guidelines in:
|
||||
*
|
||||
* Documentation/timers/timers-howto.txt
|
||||
*
|
||||
* The assumption here is that regulators will never be enabled in
|
||||
* atomic context and therefore sleeping functions can be used.
|
||||
*/
|
||||
if (delay) {
|
||||
unsigned int ms = delay / 1000;
|
||||
unsigned int us = delay % 1000;
|
||||
|
||||
if (ms > 0) {
|
||||
/*
|
||||
* For small enough values, handle super-millisecond
|
||||
* delays in the usleep_range() call below.
|
||||
*/
|
||||
if (ms < 20)
|
||||
us += ms * 1000;
|
||||
else
|
||||
msleep(ms);
|
||||
}
|
||||
|
||||
/*
|
||||
* Give the scheduler some room to coalesce with any other
|
||||
* wakeup sources. For delays shorter than 10 us, don't even
|
||||
* bother setting up high-resolution timers and just busy-
|
||||
* loop.
|
||||
*/
|
||||
if (us >= 10)
|
||||
usleep_range(us, us + 100);
|
||||
else
|
||||
udelay(us);
|
||||
}
|
||||
|
||||
trace_regulator_enable_complete(rdev_get_name(rdev));
|
||||
|
|
|
@ -23,6 +23,8 @@ static void of_get_regulation_constraints(struct device_node *np,
|
|||
const __be32 *min_uA, *max_uA, *ramp_delay;
|
||||
struct property *prop;
|
||||
struct regulation_constraints *constraints = &(*init_data)->constraints;
|
||||
int ret;
|
||||
u32 pval;
|
||||
|
||||
constraints->name = of_get_property(np, "regulator-name", NULL);
|
||||
|
||||
|
@ -73,6 +75,10 @@ static void of_get_regulation_constraints(struct device_node *np,
|
|||
else
|
||||
constraints->ramp_disable = true;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
|
||||
if (!ret)
|
||||
constraints->enable_time = pval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -95,6 +95,7 @@ struct regulator_state {
|
|||
* @initial_state: Suspend state to set by default.
|
||||
* @initial_mode: Mode to set at startup.
|
||||
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
|
||||
* @enable_time: Turn-on time of the rails (unit: microseconds)
|
||||
*/
|
||||
struct regulation_constraints {
|
||||
|
||||
|
@ -129,6 +130,7 @@ struct regulation_constraints {
|
|||
unsigned int initial_mode;
|
||||
|
||||
unsigned int ramp_delay;
|
||||
unsigned int enable_time;
|
||||
|
||||
/* constraint flags */
|
||||
unsigned always_on:1; /* regulator never off when system is on */
|
||||
|
|
Loading…
Reference in a new issue