Merge remote-tracking branches 'regulator/topic/can-change', 'regulator/topic/constrain', 'regulator/topic/debugfs' and 'regulator/topic/doc' into regulator-next
This commit is contained in:
commit
78d5501cf4
@ -132,6 +132,19 @@ static bool have_full_constraints(void)
|
||||
return has_full_constraints || of_have_populated_dt();
|
||||
}
|
||||
|
||||
static bool regulator_ops_is_valid(struct regulator_dev *rdev, int ops)
|
||||
{
|
||||
if (!rdev->constraints) {
|
||||
rdev_err(rdev, "no constraints\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rdev->constraints->valid_ops_mask & ops)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct regulator_dev *rdev_get_supply(struct regulator_dev *rdev)
|
||||
{
|
||||
if (rdev && rdev->supply)
|
||||
@ -198,28 +211,13 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
|
||||
return regnode;
|
||||
}
|
||||
|
||||
static int _regulator_can_change_status(struct regulator_dev *rdev)
|
||||
{
|
||||
if (!rdev->constraints)
|
||||
return 0;
|
||||
|
||||
if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Platform voltage constraint check */
|
||||
static int regulator_check_voltage(struct regulator_dev *rdev,
|
||||
int *min_uV, int *max_uV)
|
||||
{
|
||||
BUG_ON(*min_uV > *max_uV);
|
||||
|
||||
if (!rdev->constraints) {
|
||||
rdev_err(rdev, "no constraints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
|
||||
rdev_err(rdev, "voltage operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
@ -275,11 +273,7 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
|
||||
{
|
||||
BUG_ON(*min_uA > *max_uA);
|
||||
|
||||
if (!rdev->constraints) {
|
||||
rdev_err(rdev, "no constraints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) {
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_CURRENT)) {
|
||||
rdev_err(rdev, "current operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
@ -312,11 +306,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!rdev->constraints) {
|
||||
rdev_err(rdev, "no constraints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) {
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_MODE)) {
|
||||
rdev_err(rdev, "mode operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
@ -333,20 +323,6 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* dynamic regulator mode switching constraint check */
|
||||
static int regulator_check_drms(struct regulator_dev *rdev)
|
||||
{
|
||||
if (!rdev->constraints) {
|
||||
rdev_err(rdev, "no constraints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) {
|
||||
rdev_dbg(rdev, "drms operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t regulator_uV_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -692,8 +668,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
|
||||
* first check to see if we can set modes at all, otherwise just
|
||||
* tell the consumer everything is OK.
|
||||
*/
|
||||
err = regulator_check_drms(rdev);
|
||||
if (err < 0)
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
|
||||
return 0;
|
||||
|
||||
if (!rdev->desc->ops->get_optimum_mode &&
|
||||
@ -891,7 +866,7 @@ static void print_constraints(struct regulator_dev *rdev)
|
||||
rdev_dbg(rdev, "%s\n", buf);
|
||||
|
||||
if ((constraints->min_uV != constraints->max_uV) &&
|
||||
!(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
|
||||
!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE))
|
||||
rdev_warn(rdev,
|
||||
"Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
|
||||
}
|
||||
@ -933,6 +908,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
if (target_min != current_uV || target_max != current_uV) {
|
||||
rdev_info(rdev, "Bringing %duV into %d-%duV\n",
|
||||
current_uV, target_min, target_max);
|
||||
ret = _regulator_do_set_voltage(
|
||||
rdev, target_min, target_max);
|
||||
if (ret < 0) {
|
||||
@ -1277,6 +1254,55 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static ssize_t constraint_flags_read_file(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
const struct regulator *regulator = file->private_data;
|
||||
const struct regulation_constraints *c = regulator->rdev->constraints;
|
||||
char *buf;
|
||||
ssize_t ret;
|
||||
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snprintf(buf, PAGE_SIZE,
|
||||
"always_on: %u\n"
|
||||
"boot_on: %u\n"
|
||||
"apply_uV: %u\n"
|
||||
"ramp_disable: %u\n"
|
||||
"soft_start: %u\n"
|
||||
"pull_down: %u\n"
|
||||
"over_current_protection: %u\n",
|
||||
c->always_on,
|
||||
c->boot_on,
|
||||
c->apply_uV,
|
||||
c->ramp_disable,
|
||||
c->soft_start,
|
||||
c->pull_down,
|
||||
c->over_current_protection);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const struct file_operations constraint_flags_fops = {
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
.open = simple_open,
|
||||
.read = constraint_flags_read_file,
|
||||
.llseek = default_llseek,
|
||||
#endif
|
||||
};
|
||||
|
||||
#define REG_STR_SIZE 64
|
||||
|
||||
static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
@ -1332,6 +1358,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
®ulator->min_uV);
|
||||
debugfs_create_u32("max_uV", 0444, regulator->debugfs,
|
||||
®ulator->max_uV);
|
||||
debugfs_create_file("constraint_flags", 0444,
|
||||
regulator->debugfs, regulator,
|
||||
&constraint_flags_fops);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1339,7 +1368,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
|
||||
* it is then we don't need to do nearly so much work for
|
||||
* enable/disable calls.
|
||||
*/
|
||||
if (!_regulator_can_change_status(rdev) &&
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS) &&
|
||||
_regulator_is_enabled(rdev))
|
||||
regulator->always_on = true;
|
||||
|
||||
@ -2117,15 +2146,15 @@ static int _regulator_enable(struct regulator_dev *rdev)
|
||||
lockdep_assert_held_once(&rdev->mutex);
|
||||
|
||||
/* check voltage and requested load before enabling */
|
||||
if (rdev->constraints &&
|
||||
(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
|
||||
drms_uA_update(rdev);
|
||||
|
||||
if (rdev->use_count == 0) {
|
||||
/* The regulator may on if it's not switchable or left on */
|
||||
ret = _regulator_is_enabled(rdev);
|
||||
if (ret == -EINVAL || ret == 0) {
|
||||
if (!_regulator_can_change_status(rdev))
|
||||
if (!regulator_ops_is_valid(rdev,
|
||||
REGULATOR_CHANGE_STATUS))
|
||||
return -EPERM;
|
||||
|
||||
ret = _regulator_do_enable(rdev);
|
||||
@ -2227,7 +2256,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
|
||||
(rdev->constraints && !rdev->constraints->always_on)) {
|
||||
|
||||
/* we are last user */
|
||||
if (_regulator_can_change_status(rdev)) {
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) {
|
||||
ret = _notifier_call_chain(rdev,
|
||||
REGULATOR_EVENT_PRE_DISABLE,
|
||||
NULL);
|
||||
@ -2248,10 +2277,7 @@ static int _regulator_disable(struct regulator_dev *rdev)
|
||||
|
||||
rdev->use_count = 0;
|
||||
} else if (rdev->use_count > 1) {
|
||||
|
||||
if (rdev->constraints &&
|
||||
(rdev->constraints->valid_ops_mask &
|
||||
REGULATOR_CHANGE_DRMS))
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_DRMS))
|
||||
drms_uA_update(rdev);
|
||||
|
||||
rdev->use_count--;
|
||||
@ -2495,8 +2521,7 @@ int regulator_can_change_voltage(struct regulator *regulator)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
|
||||
if (rdev->constraints &&
|
||||
(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
|
||||
if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
|
||||
if (rdev->desc->n_voltages - rdev->desc->linear_min_sel > 1)
|
||||
return 1;
|
||||
|
||||
@ -2650,7 +2675,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
|
||||
int i, voltages, ret;
|
||||
|
||||
/* If we can't change voltage check the current voltage */
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
|
||||
ret = regulator_get_voltage(regulator);
|
||||
if (ret >= 0)
|
||||
return min_uV <= ret && ret <= max_uV;
|
||||
@ -2856,7 +2881,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
|
||||
* return successfully even though the regulator does not support
|
||||
* changing the voltage.
|
||||
*/
|
||||
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
|
||||
current_uV = _regulator_get_voltage(rdev);
|
||||
if (min_uV <= current_uV && current_uV <= max_uV) {
|
||||
regulator->min_uV = min_uV;
|
||||
@ -3388,8 +3413,7 @@ int regulator_allow_bypass(struct regulator *regulator, bool enable)
|
||||
if (!rdev->desc->ops->set_bypass)
|
||||
return 0;
|
||||
|
||||
if (rdev->constraints &&
|
||||
!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_BYPASS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
@ -4429,7 +4453,7 @@ static int __init regulator_late_cleanup(struct device *dev, void *data)
|
||||
if (c && c->always_on)
|
||||
return 0;
|
||||
|
||||
if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
|
||||
if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
|
@ -224,7 +224,7 @@ int regulator_bulk_force_disable(int num_consumers,
|
||||
void regulator_bulk_free(int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
|
||||
int regulator_can_change_voltage(struct regulator *regulator);
|
||||
int __deprecated regulator_can_change_voltage(struct regulator *regulator);
|
||||
int regulator_count_voltages(struct regulator *regulator);
|
||||
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
|
||||
int regulator_is_supported_voltage(struct regulator *regulator,
|
||||
@ -436,7 +436,7 @@ static inline void regulator_bulk_free(int num_consumers,
|
||||
{
|
||||
}
|
||||
|
||||
static inline int regulator_can_change_voltage(struct regulator *regulator)
|
||||
static inline int __deprecated regulator_can_change_voltage(struct regulator *regulator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -93,6 +93,9 @@ struct regulator_linear_range {
|
||||
* @get_current_limit: Get the configured limit for a current-limited regulator.
|
||||
* @set_input_current_limit: Configure an input limit.
|
||||
*
|
||||
* @set_over_current_protection: Support capability of automatically shutting
|
||||
* down when detecting an over current event.
|
||||
*
|
||||
* @set_active_discharge: Set active discharge enable/disable of regulators.
|
||||
*
|
||||
* @set_mode: Set the configured operating mode for the regulator.
|
||||
@ -255,6 +258,8 @@ enum regulator_type {
|
||||
*
|
||||
* @vsel_reg: Register for selector when using regulator_regmap_X_voltage_
|
||||
* @vsel_mask: Mask for register bitfield used for selector
|
||||
* @csel_reg: Register for TPS65218 LS3 current regulator
|
||||
* @csel_mask: Mask for TPS65218 LS3 current regulator
|
||||
* @apply_reg: Register for initiate voltage change on the output when
|
||||
* using regulator_set_voltage_sel_regmap
|
||||
* @apply_bit: Register bitfield used for initiate voltage change on the
|
||||
|
@ -97,6 +97,7 @@ struct regulator_state {
|
||||
* @ramp_disable: Disable ramp delay when initialising or when setting voltage.
|
||||
* @soft_start: Enable soft start so that voltage ramps slowly.
|
||||
* @pull_down: Enable pull down when regulator is disabled.
|
||||
* @over_current_protection: Auto disable on over current event.
|
||||
*
|
||||
* @input_uV: Input voltage for regulator when supplied by another regulator.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user