regulator: Updates for v4.11

Quite a lot of work going on the core this release, mainly around system
 initialization, but a quiet release for drivers:
 
  - Fixes for registration of multiple regulators on a PMIC from Javier
    Martinez Canillas and Jon Hunter.
  - Cleanups to the regulator_get() code from Dmitry Torokhov
  - Lots of constifcation of structs from Bhumika Goyal
  - Support for Motorola CPCAP regulators from Tony Lindgren.
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCAAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAlirPJwTHGJyb29uaWVA
 a2VybmVsLm9yZwAKCRAk1otyXVSH0OJyB/sH4ug2B14/NQjWg/K3M382lUcV24+x
 rgq7ucelmHStrqnSU/DTauGL3uoU3Mc9ibGx7nK4SCWaylHpcZjI42dqG+Tkw/CG
 /NlF++JOD0lmlXN1kUTqjFyLOGX9Mt5p4Rnbh3xWWJ5Gq30y6IcIJXILrs/9zI4G
 OPhAp5Zq7cwT/00PEIxXtI2OcWx9cIeOIwmwE8S0hvNkVQ5oUz5VV+43ZooFVXrN
 4l4GzJgEu3huF/zaWq0lW0HHlhWbLcZGNzg8B+6//V3Xrq7dapyQ5vXpARC8DsFm
 Q1n2eJlsdbwjTiQy5xOCmk76GnneGt8/6ifhNKidc5LKfoy7DVfPfIF7
 =qvYg
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "Quite a lot of work going on the core this release, mainly around
  system initialization, but a quiet release for drivers:

   - fixes for registration of multiple regulators on a PMIC from Javier
     Martinez Canillas and Jon Hunter.

   - cleanups to the regulator_get() code from Dmitry Torokhov

   - lots of constifcation of structs from Bhumika Goyal

   - support for Motorola CPCAP regulators from Tony Lindgren"

* tag 'regulator-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (52 commits)
  regulator: core: Resolve supplies before disabling unused regulators
  regulator: Fix regulator_summary for deviceless consumers
  regulator: tps65086: Fix DT node referencing in of_parse_cb
  regulator: tps65086: Fix expected switch DT node names
  regulator: core: simplify _regulator_get()
  regulator: core: have regulator_dev_lookup() return ERR_PTR-encoded errors
  regulator: gpio: correct default type
  regulator: cpcap: Add basic regulator support
  regulator: core: fix typo in regulator_bulk_disable()
  regulator: core: optimize devm_regulator_bulk_get()
  regulator: core: simplify regulator_bulk_force_disable()
  regulator: core: have _regulator_get() accept get_type argument
  regulator: core: remove dead code in _regulator_get()
  regulator: rn5t618: constify regulator_ops structure
  regulator: rc5t583-regulator: constify regulator_ops structure
  regulator: pv88090-regulator: constify regulator_ops structure
  regulator: pv88080-regulator: constify regulator_ops structure
  regulator: pv88060-regulator: constify regulator_ops structure
  regulator: pfuze100-regulator: constify regulator_ops structure
  regulator: pcf50633-regulator: constify regulator_ops structure
  ...
This commit is contained in:
Linus Torvalds 2017-02-20 17:23:57 -08:00
commit f790bd9c8e
48 changed files with 909 additions and 203 deletions

View File

@ -14,6 +14,7 @@ Optional properties:
- anatop-delay-bit-shift: Bit shift for the step time register
- anatop-delay-bit-width: Number of bits used in the step time register
- vin-supply: The supply for this regulator
- anatop-enable-bit: Regulator enable bit offset
Any property defined as part of the core regulator
binding, defined in regulator.txt, can also be used.

View File

@ -0,0 +1,34 @@
Motorola CPCAP PMIC voltage regulators
------------------------------------
Requires node properties:
- "compatible" value one of:
"motorola,cpcap-regulator"
"motorola,mapphone-cpcap-regulator"
Required regulator properties:
- "regulator-name"
- "regulator-enable-ramp-delay"
- "regulator-min-microvolt"
- "regulator-max-microvolt"
Optional regulator properties:
- "regulator-boot-on"
See Documentation/devicetree/bindings/regulator/regulator.txt
for more details about the regulator properties.
Example:
cpcap_regulator: regulator {
compatible = "motorola,cpcap-regulator";
cpcap_regulators: regulators {
sw5: SW5 {
regulator-min-microvolt = <5050000>;
regulator-max-microvolt = <5050000>;
regulator-enable-ramp-delay = <50000>;
regulator-boot-on;
};
};
};

View File

@ -13,7 +13,7 @@ Optional properties:
- startup-delay-us : Startup time in microseconds.
- enable-active-high : Polarity of GPIO is active high (default is low).
- regulator-type : Specifies what is being regulated, must be either
"voltage" or "current", defaults to current.
"voltage" or "current", defaults to voltage.
Any property defined as part of the core regulator binding defined in
regulator.txt can also be used.

View File

@ -22,6 +22,7 @@ Regulator nodes are identified by their compatible:
"qcom,rpm-pm8841-regulators"
"qcom,rpm-pm8916-regulators"
"qcom,rpm-pm8941-regulators"
"qcom,rpm-pm8994-regulators"
"qcom,rpm-pma8084-regulators"
- vdd_s1-supply:
@ -68,6 +69,56 @@ Regulator nodes are identified by their compatible:
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
- vdd_s9-supply:
- vdd_s10-supply:
- vdd_s11-supply:
- vdd_s12-supply:
- vdd_l1-supply:
- vdd_l2_l26_l28-supply:
- vdd_l3_l11-supply:
- vdd_l4_l27_l31-supply:
- vdd_l5_l7-supply:
- vdd_l6_l12_l32-supply:
- vdd_l5_l7-supply:
- vdd_l8_l16_l30-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l3_l11-supply:
- vdd_l6_l12_l32-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l14_l15-supply:
- vdd_l14_l15-supply:
- vdd_l8_l16_l30-supply:
- vdd_l17_l29-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l20_l21-supply:
- vdd_l20_l21-supply:
- vdd_l9_l10_l18_l22-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l13_l19_l23_l24-supply:
- vdd_l25-supply:
- vdd_l2_l26_l28-supply:
- vdd_l4_l27_l31-supply:
- vdd_l2_l26_l28-supply:
- vdd_l17_l29-supply:
- vdd_l8_l16_l30-supply:
- vdd_l4_l27_l31-supply:
- vdd_l6_l12_l32-supply:
- vdd_lvs1_2-supply:
Usage: optional (pm8994 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
@ -113,6 +164,11 @@ pm8941:
l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2,
lvs3, 5vs1, 5vs2
pm8994:
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5,
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,
l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2
pma8084:
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5,
l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20,

View File

@ -180,7 +180,7 @@ static int pm800_get_current_limit(struct regulator_dev *rdev)
return info->max_ua;
}
static struct regulator_ops pm800_volt_range_ops = {
static const struct regulator_ops pm800_volt_range_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
@ -191,7 +191,7 @@ static struct regulator_ops pm800_volt_range_ops = {
.get_current_limit = pm800_get_current_limit,
};
static struct regulator_ops pm800_volt_table_ops = {
static const struct regulator_ops pm800_volt_table_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.set_voltage_sel = regulator_set_voltage_sel_regmap,

View File

@ -220,7 +220,7 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
return ret;
}
static struct regulator_ops pm8607_regulator_ops = {
static const struct regulator_ops pm8607_regulator_ops = {
.list_voltage = pm8607_list_voltage,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -229,7 +229,7 @@ static struct regulator_ops pm8607_regulator_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops pm8606_preg_ops = {
static const struct regulator_ops pm8606_preg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -163,6 +163,13 @@ config REGULATOR_BCM590XX
BCM590xx PMUs. This will enable support for the software
controllable LDO/Switching regulators.
config REGULATOR_CPCAP
tristate "Motorola CPCAP regulator"
depends on MFD_CPCAP
help
Say y here for CPCAP regulator found on some Motorola phones
and tablets such as Droid 4.
config REGULATOR_DA903X
tristate "Dialog Semiconductor DA9030/DA9034 regulators"
depends on PMIC_DA903X

View File

@ -11,6 +11,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PM800) += 88pm800.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o

View File

@ -97,7 +97,7 @@ static int aat2870_ldo_is_enabled(struct regulator_dev *rdev)
return val & ri->enable_mask ? 1 : 0;
}
static struct regulator_ops aat2870_ldo_ops = {
static const struct regulator_ops aat2870_ldo_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.set_voltage_sel = aat2870_ldo_set_voltage_sel,

View File

@ -69,7 +69,7 @@ static const struct regulator_linear_range act8945a_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
};
static struct regulator_ops act8945a_ops = {
static const struct regulator_ops act8945a_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,

View File

@ -181,7 +181,7 @@ static int ad5398_disable(struct regulator_dev *rdev)
return ret;
}
static struct regulator_ops ad5398_ops = {
static const struct regulator_ops ad5398_ops = {
.get_current_limit = ad5398_get_current_limit,
.set_current_limit = ad5398_set_current_limit,
.enable = ad5398_enable,

View File

@ -301,7 +301,19 @@ static int anatop_regulator_probe(struct platform_device *pdev)
return -EINVAL;
}
} else {
u32 enable_bit;
rdesc->ops = &anatop_rops;
if (!of_property_read_u32(np, "anatop-enable-bit",
&enable_bit)) {
anatop_rops.enable = regulator_enable_regmap;
anatop_rops.disable = regulator_disable_regmap;
anatop_rops.is_enabled = regulator_is_enabled_regmap;
rdesc->enable_reg = sreg->control_reg;
rdesc->enable_mask = BIT(enable_bit);
}
}
/* register regulator */

View File

@ -109,7 +109,7 @@ static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT;
}
static struct regulator_ops arizona_ldo1_hc_ops = {
static const struct regulator_ops arizona_ldo1_hc_ops = {
.list_voltage = arizona_ldo1_hc_list_voltage,
.map_voltage = arizona_ldo1_hc_map_voltage,
.get_voltage_sel = arizona_ldo1_hc_get_voltage_sel,
@ -135,7 +135,7 @@ static const struct regulator_desc arizona_ldo1_hc = {
.owner = THIS_MODULE,
};
static struct regulator_ops arizona_ldo1_ops = {
static const struct regulator_ops arizona_ldo1_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,

View File

@ -45,6 +45,7 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
struct arizona_micsupp *micsupp =
container_of(work, struct arizona_micsupp, check_cp_work);
struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm;
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
struct arizona *arizona = micsupp->arizona;
struct regmap *regmap = arizona->regmap;
unsigned int reg;
@ -59,9 +60,10 @@ static void arizona_micsupp_check_cp(struct work_struct *work)
if (dapm) {
if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
ARIZONA_CPMIC_ENA)
snd_soc_dapm_force_enable_pin(dapm, "MICSUPP");
snd_soc_component_force_enable_pin(component,
"MICSUPP");
else
snd_soc_dapm_disable_pin(dapm, "MICSUPP");
snd_soc_component_disable_pin(component, "MICSUPP");
snd_soc_dapm_sync(dapm);
}
@ -104,7 +106,7 @@ static int arizona_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
return ret;
}
static struct regulator_ops arizona_micsupp_ops = {
static const struct regulator_ops arizona_micsupp_ops = {
.enable = arizona_micsupp_enable,
.disable = arizona_micsupp_disable,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -82,7 +82,7 @@ static unsigned int as3711_get_mode_sd(struct regulator_dev *rdev)
return -EINVAL;
}
static struct regulator_ops as3711_sd_ops = {
static const struct regulator_ops as3711_sd_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -94,7 +94,7 @@ static struct regulator_ops as3711_sd_ops = {
.set_mode = as3711_set_mode_sd,
};
static struct regulator_ops as3711_aldo_ops = {
static const struct regulator_ops as3711_aldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -104,7 +104,7 @@ static struct regulator_ops as3711_aldo_ops = {
.map_voltage = regulator_map_voltage_linear_range,
};
static struct regulator_ops as3711_dldo_ops = {
static const struct regulator_ops as3711_dldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,

View File

@ -128,11 +128,11 @@
.ops = &axp20x_ops_range, \
}
static struct regulator_ops axp20x_ops_fixed = {
static const struct regulator_ops axp20x_ops_fixed = {
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops axp20x_ops_range = {
static const struct regulator_ops axp20x_ops_range = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear_range,
@ -141,7 +141,7 @@ static struct regulator_ops axp20x_ops_range = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops axp20x_ops = {
static const struct regulator_ops axp20x_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
@ -150,7 +150,7 @@ static struct regulator_ops axp20x_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops axp20x_ops_sw = {
static const struct regulator_ops axp20x_ops_sw = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -250,7 +250,7 @@ static int bcm590xx_get_enable_register(int id)
return reg;
}
static struct regulator_ops bcm590xx_ops_ldo = {
static const struct regulator_ops bcm590xx_ops_ldo = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -260,7 +260,7 @@ static struct regulator_ops bcm590xx_ops_ldo = {
.map_voltage = regulator_map_voltage_iterate,
};
static struct regulator_ops bcm590xx_ops_dcdc = {
static const struct regulator_ops bcm590xx_ops_dcdc = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -270,7 +270,7 @@ static struct regulator_ops bcm590xx_ops_dcdc = {
.map_voltage = regulator_map_voltage_linear_range,
};
static struct regulator_ops bcm590xx_ops_vbus = {
static const struct regulator_ops bcm590xx_ops_vbus = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,

View File

@ -1455,12 +1455,14 @@ static struct regulator_dev *regulator_lookup_by_name(const char *name)
* lookup could succeed in the future.
*
* If successful, returns a struct regulator_dev that corresponds to the name
* @supply and with the embedded struct device refcount incremented by one,
* or NULL on failure. The refcount must be dropped by calling put_device().
* @supply and with the embedded struct device refcount incremented by one.
* The refcount must be dropped by calling put_device().
* On failure one of the following ERR-PTR-encoded values is returned:
* -ENODEV if lookup fails permanently, -EPROBE_DEFER if lookup could succeed
* in the future.
*/
static struct regulator_dev *regulator_dev_lookup(struct device *dev,
const char *supply,
int *ret)
const char *supply)
{
struct regulator_dev *r;
struct device_node *node;
@ -1476,16 +1478,12 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
r = of_find_regulator_by_node(node);
if (r)
return r;
*ret = -EPROBE_DEFER;
return NULL;
} else {
/*
* If we couldn't even get the node then it's
* not just that the device didn't register
* yet, there's no node and we'll never
* succeed.
* We have a node, but there is no device.
* assume it has not registered yet.
*/
*ret = -ENODEV;
return ERR_PTR(-EPROBE_DEFER);
}
}
@ -1506,13 +1504,16 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
if (strcmp(map->supply, supply) == 0 &&
get_device(&map->regulator->dev)) {
mutex_unlock(&regulator_list_mutex);
return map->regulator;
r = map->regulator;
break;
}
}
mutex_unlock(&regulator_list_mutex);
return NULL;
if (r)
return r;
return ERR_PTR(-ENODEV);
}
static int regulator_resolve_supply(struct regulator_dev *rdev)
@ -1529,8 +1530,10 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
if (rdev->supply)
return 0;
r = regulator_dev_lookup(dev, rdev->supply_name, &ret);
if (!r) {
r = regulator_dev_lookup(dev, rdev->supply_name);
if (IS_ERR(r)) {
ret = PTR_ERR(r);
if (ret == -ENODEV) {
/*
* No supply was specified for this regulator and
@ -1553,6 +1556,19 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
}
/*
* If the supply's parent device is not the same as the
* regulator's parent device, then ensure the parent device
* is bound before we resolve the supply, in case the parent
* device get probe deferred and unregisters the supply.
*/
if (r->dev.parent && r->dev.parent != rdev->dev.parent) {
if (!device_is_bound(r->dev.parent)) {
put_device(&r->dev);
return -EPROBE_DEFER;
}
}
/* Recursively resolve the supply of the supply */
ret = regulator_resolve_supply(r);
if (ret < 0) {
@ -1580,69 +1596,72 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
/* Internal regulator request function */
static struct regulator *_regulator_get(struct device *dev, const char *id,
bool exclusive, bool allow_dummy)
struct regulator *_regulator_get(struct device *dev, const char *id,
enum regulator_get_type get_type)
{
struct regulator_dev *rdev;
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
const char *devname = NULL;
struct regulator *regulator;
const char *devname = dev ? dev_name(dev) : "deviceless";
int ret;
if (get_type >= MAX_GET_TYPE) {
dev_err(dev, "invalid type %d in %s\n", get_type, __func__);
return ERR_PTR(-EINVAL);
}
if (id == NULL) {
pr_err("get() with no identifier\n");
return ERR_PTR(-EINVAL);
}
if (dev)
devname = dev_name(dev);
if (have_full_constraints())
ret = -ENODEV;
else
ret = -EPROBE_DEFER;
rdev = regulator_dev_lookup(dev, id, &ret);
if (rdev)
goto found;
regulator = ERR_PTR(ret);
rdev = regulator_dev_lookup(dev, id);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
/*
* If we have return value from dev_lookup fail, we do not expect to
* succeed, so, quit with appropriate error value
* If regulator_dev_lookup() fails with error other
* than -ENODEV our job here is done, we simply return it.
*/
if (ret && ret != -ENODEV)
return regulator;
if (ret != -ENODEV)
return ERR_PTR(ret);
if (!devname)
devname = "deviceless";
/*
* Assume that a regulator is physically present and enabled
* even if it isn't hooked up and just provide a dummy.
*/
if (have_full_constraints() && allow_dummy) {
pr_warn("%s supply %s not found, using dummy regulator\n",
devname, id);
rdev = dummy_regulator_rdev;
get_device(&rdev->dev);
goto found;
/* Don't log an error when called from regulator_get_optional() */
} else if (!have_full_constraints() || exclusive) {
dev_warn(dev, "dummy supplies not allowed\n");
if (!have_full_constraints()) {
dev_warn(dev,
"incomplete constraints, dummy supplies not allowed\n");
return ERR_PTR(-ENODEV);
}
return regulator;
switch (get_type) {
case NORMAL_GET:
/*
* Assume that a regulator is physically present and
* enabled, even if it isn't hooked up, and just
* provide a dummy.
*/
dev_warn(dev,
"%s supply %s not found, using dummy regulator\n",
devname, id);
rdev = dummy_regulator_rdev;
get_device(&rdev->dev);
break;
case EXCLUSIVE_GET:
dev_warn(dev,
"dummy supplies not allowed for exclusive requests\n");
/* fall through */
default:
return ERR_PTR(-ENODEV);
}
}
found:
if (rdev->exclusive) {
regulator = ERR_PTR(-EPERM);
put_device(&rdev->dev);
return regulator;
}
if (exclusive && rdev->open_count) {
if (get_type == EXCLUSIVE_GET && rdev->open_count) {
regulator = ERR_PTR(-EBUSY);
put_device(&rdev->dev);
return regulator;
@ -1656,6 +1675,7 @@ found:
}
if (!try_module_get(rdev->owner)) {
regulator = ERR_PTR(-EPROBE_DEFER);
put_device(&rdev->dev);
return regulator;
}
@ -1669,7 +1689,7 @@ found:
}
rdev->open_count++;
if (exclusive) {
if (get_type == EXCLUSIVE_GET) {
rdev->exclusive = 1;
ret = _regulator_is_enabled(rdev);
@ -1697,7 +1717,7 @@ found:
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
return _regulator_get(dev, id, false, true);
return _regulator_get(dev, id, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(regulator_get);
@ -1724,7 +1744,7 @@ EXPORT_SYMBOL_GPL(regulator_get);
*/
struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
{
return _regulator_get(dev, id, true, false);
return _regulator_get(dev, id, EXCLUSIVE_GET);
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
@ -1750,7 +1770,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive);
*/
struct regulator *regulator_get_optional(struct device *dev, const char *id)
{
return _regulator_get(dev, id, false, false);
return _regulator_get(dev, id, OPTIONAL_GET);
}
EXPORT_SYMBOL_GPL(regulator_get_optional);
@ -3660,7 +3680,7 @@ err:
for (++i; i < num_consumers; ++i) {
r = regulator_enable(consumers[i].consumer);
if (r != 0)
pr_err("Failed to reename %s: %d\n",
pr_err("Failed to re-enable %s: %d\n",
consumers[i].supply, r);
}
@ -3686,21 +3706,17 @@ int regulator_bulk_force_disable(int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
int ret;
int ret = 0;
for (i = 0; i < num_consumers; i++)
for (i = 0; i < num_consumers; i++) {
consumers[i].ret =
regulator_force_disable(consumers[i].consumer);
for (i = 0; i < num_consumers; i++) {
if (consumers[i].ret != 0) {
/* Store first error for reporting */
if (consumers[i].ret && !ret)
ret = consumers[i].ret;
goto out;
}
}
return 0;
out:
return ret;
}
EXPORT_SYMBOL_GPL(regulator_bulk_force_disable);
@ -4391,12 +4407,13 @@ static void regulator_summary_show_subtree(struct seq_file *s,
seq_puts(s, "\n");
list_for_each_entry(consumer, &rdev->consumer_list, list) {
if (consumer->dev->class == &regulator_class)
if (consumer->dev && consumer->dev->class == &regulator_class)
continue;
seq_printf(s, "%*s%-*s ",
(level + 1) * 3 + 1, "",
30 - (level + 1) * 3, dev_name(consumer->dev));
30 - (level + 1) * 3,
consumer->dev ? dev_name(consumer->dev) : "deviceless");
switch (rdev->desc->type) {
case REGULATOR_VOLTAGE:
@ -4540,6 +4557,16 @@ static int __init regulator_init_complete(void)
if (of_have_populated_dt())
has_full_constraints = true;
/*
* Regulators may had failed to resolve their input supplies
* when were registered, either because the input supply was
* not registered yet or because its parent device was not
* bound yet. So attempt to resolve the input supplies for
* pending regulators before trying to disable unused ones.
*/
class_for_each_device(&regulator_class, NULL, NULL,
regulator_register_resolve_supply);
/* If we have a full configuration then disable any regulators
* we have permission to change the status for and which are
* not in use or always_on. This is effectively the default

View File

@ -0,0 +1,464 @@
/*
* Motorola CPCAP PMIC regulator driver
*
* Based on cpcap-regulator.c from Motorola Linux kernel tree
* Copyright (C) 2009-2011 Motorola, Inc.
*
* Rewritten for mainline kernel to use device tree and regmap
* Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/motorola-cpcap.h>
/*
* Resource assignment register bits. These seem to control the state
* idle modes adn are used at least for omap4.
*/
/* CPCAP_REG_ASSIGN2 bits - Resource Assignment 2 */
#define CPCAP_BIT_VSDIO_SEL BIT(15)
#define CPCAP_BIT_VDIG_SEL BIT(14)
#define CPCAP_BIT_VCAM_SEL BIT(13)
#define CPCAP_BIT_SW6_SEL BIT(12)
#define CPCAP_BIT_SW5_SEL BIT(11)
#define CPCAP_BIT_SW4_SEL BIT(10)
#define CPCAP_BIT_SW3_SEL BIT(9)
#define CPCAP_BIT_SW2_SEL BIT(8)
#define CPCAP_BIT_SW1_SEL BIT(7)
/* CPCAP_REG_ASSIGN3 bits - Resource Assignment 3 */
#define CPCAP_BIT_VUSBINT2_SEL BIT(15)
#define CPCAP_BIT_VUSBINT1_SEL BIT(14)
#define CPCAP_BIT_VVIB_SEL BIT(13)
#define CPCAP_BIT_VWLAN1_SEL BIT(12)
#define CPCAP_BIT_VRF1_SEL BIT(11)
#define CPCAP_BIT_VHVIO_SEL BIT(10)
#define CPCAP_BIT_VDAC_SEL BIT(9)
#define CPCAP_BIT_VUSB_SEL BIT(8)
#define CPCAP_BIT_VSIM_SEL BIT(7)
#define CPCAP_BIT_VRFREF_SEL BIT(6)
#define CPCAP_BIT_VPLL_SEL BIT(5)
#define CPCAP_BIT_VFUSE_SEL BIT(4)
#define CPCAP_BIT_VCSI_SEL BIT(3)
#define CPCAP_BIT_SPARE_14_2 BIT(2)
#define CPCAP_BIT_VWLAN2_SEL BIT(1)
#define CPCAP_BIT_VRF2_SEL BIT(0)
/* CPCAP_REG_ASSIGN4 bits - Resource Assignment 4 */
#define CPCAP_BIT_VAUDIO_SEL BIT(0)
/*
* Enable register bits. At least CPCAP_BIT_AUDIO_LOW_PWR is generic,
* and not limited to audio regulator. Let's use the Motorola kernel
* naming for now until we have a better understanding of the other
* enable register bits. No idea why BIT(3) is not defined.
*/
#define CPCAP_BIT_AUDIO_LOW_PWR BIT(6)
#define CPCAP_BIT_AUD_LOWPWR_SPEED BIT(5)
#define CPCAP_BIT_VAUDIOPRISTBY BIT(4)
#define CPCAP_BIT_VAUDIO_MODE1 BIT(2)
#define CPCAP_BIT_VAUDIO_MODE0 BIT(1)
#define CPCAP_BIT_V_AUDIO_EN BIT(0)
/*
* Off mode configuration bit. Used currently only by SW5 on omap4. There's
* the following comment in Motorola Linux kernel tree for it:
*
* When set in the regulator mode, the regulator assignment will be changed
* to secondary when the regulator is disabled. The mode will be set back to
* primary when the regulator is turned on.
*/
#define CPCAP_REG_OFF_MODE_SEC BIT(15)
/**
* SoC specific configuraion for CPCAP regulator. There are at least three
* different SoCs each with their own parameters: omap3, omap4 and tegra2.
*
* The assign_reg and assign_mask seem to allow toggling between primary
* and secondary mode that at least omap4 uses for off mode.
*/
struct cpcap_regulator {
struct regulator_desc rdesc;
const u16 assign_reg;
const u16 assign_mask;
const u16 vsel_shift;
};
#define CPCAP_REG(_ID, reg, assignment_reg, assignment_mask, val_tbl, \
mode_mask, volt_mask, volt_shft, \
mode_val, off_val, volt_trans_time) { \
.rdesc = { \
.name = #_ID, \
.of_match = of_match_ptr(#_ID), \
.ops = &cpcap_regulator_ops, \
.regulators_node = of_match_ptr("regulators"), \
.type = REGULATOR_VOLTAGE, \
.id = CPCAP_##_ID, \
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(val_tbl), \
.volt_table = (val_tbl), \
.vsel_reg = (reg), \
.vsel_mask = (volt_mask), \
.enable_reg = (reg), \
.enable_mask = (mode_mask), \
.enable_val = (mode_val), \
.disable_val = (off_val), \
.ramp_delay = (volt_trans_time), \
}, \
.assign_reg = (assignment_reg), \
.assign_mask = (assignment_mask), \
.vsel_shift = (volt_shft), \
}
struct cpcap_ddata {
struct regmap *reg;
struct device *dev;
const struct cpcap_regulator *soc;
};
enum cpcap_regulator_id {
CPCAP_SW1,
CPCAP_SW2,
CPCAP_SW3,
CPCAP_SW4,
CPCAP_SW5,
CPCAP_SW6,
CPCAP_VCAM,
CPCAP_VCSI,
CPCAP_VDAC,
CPCAP_VDIG,
CPCAP_VFUSE,
CPCAP_VHVIO,
CPCAP_VSDIO,
CPCAP_VPLL,
CPCAP_VRF1,
CPCAP_VRF2,
CPCAP_VRFREF,
CPCAP_VWLAN1,
CPCAP_VWLAN2,
CPCAP_VSIM,
CPCAP_VSIMCARD,
CPCAP_VVIB,
CPCAP_VUSB,
CPCAP_VAUDIO,
CPCAP_NR_REGULATORS,
};
/*
* We need to also configure regulator idle mode for SoC off mode if
* CPCAP_REG_OFF_MODE_SEC is set.
*/
static int cpcap_regulator_enable(struct regulator_dev *rdev)
{
struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
int error, ignore;
error = regulator_enable_regmap(rdev);
if (error)
return error;
if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
regulator->assign_mask,
regulator->assign_mask);
if (error)
ignore = regulator_disable_regmap(rdev);
}
return error;
}
/*
* We need to also configure regulator idle mode for SoC off mode if
* CPCAP_REG_OFF_MODE_SEC is set.
*/
static int cpcap_regulator_disable(struct regulator_dev *rdev)
{
struct cpcap_regulator *regulator = rdev_get_drvdata(rdev);
int error, ignore;
if (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC) {
error = regmap_update_bits(rdev->regmap, regulator->assign_reg,
regulator->assign_mask, 0);
if (error)
return error;
}
error = regulator_disable_regmap(rdev);
if (error && (rdev->desc->enable_val & CPCAP_REG_OFF_MODE_SEC)) {
ignore = regmap_update_bits(rdev->regmap, regulator->assign_reg,
regulator->assign_mask,
regulator->assign_mask);
}
return error;
}
static unsigned int cpcap_regulator_get_mode(struct regulator_dev *rdev)
{
int value;
regmap_read(rdev->regmap, rdev->desc->enable_reg, &value);
if (!(value & CPCAP_BIT_AUDIO_LOW_PWR))
return REGULATOR_MODE_STANDBY;
return REGULATOR_MODE_NORMAL;
}
static int cpcap_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
int value;
switch (mode) {
case REGULATOR_MODE_NORMAL:
value = CPCAP_BIT_AUDIO_LOW_PWR;
break;
case REGULATOR_MODE_STANDBY:
value = 0;
break;
default:
return -EINVAL;
}
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
CPCAP_BIT_AUDIO_LOW_PWR, value);
}
static struct regulator_ops cpcap_regulator_ops = {
.enable = cpcap_regulator_enable,
.disable = cpcap_regulator_disable,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_mode = cpcap_regulator_get_mode,
.set_mode = cpcap_regulator_set_mode,
};
static const unsigned int unknown_val_tbl[] = { 0, };
static const unsigned int sw5_val_tbl[] = { 0, 5050000, };
static const unsigned int vcam_val_tbl[] = { 2600000, 2700000, 2800000,
2900000, };
static const unsigned int vcsi_val_tbl[] = { 1200000, 1800000, };
static const unsigned int vdac_val_tbl[] = { 1200000, 1500000, 1800000,
2500000,};
static const unsigned int vdig_val_tbl[] = { 1200000, 1350000, 1500000,
1875000, };
static const unsigned int vfuse_val_tbl[] = { 1500000, 1600000, 1700000,
1800000, 1900000, 2000000,
2100000, 2200000, 2300000,
2400000, 2500000, 2600000,
2700000, 3150000, };
static const unsigned int vhvio_val_tbl[] = { 2775000, };
static const unsigned int vsdio_val_tbl[] = { 1500000, 1600000, 1800000,
2600000, 2700000, 2800000,
2900000, 3000000, };
static const unsigned int vpll_val_tbl[] = { 1200000, 1300000, 1400000,
1800000, };
/* Quirk: 2775000 is before 2500000 for vrf1 regulator */
static const unsigned int vrf1_val_tbl[] = { 2775000, 2500000, };
static const unsigned int vrf2_val_tbl[] = { 0, 2775000, };
static const unsigned int vrfref_val_tbl[] = { 2500000, 2775000, };
static const unsigned int vwlan1_val_tbl[] = { 1800000, 1900000, };
static const unsigned int vwlan2_val_tbl[] = { 2775000, 3000000, 3300000,
3300000, };
static const unsigned int vsim_val_tbl[] = { 1800000, 2900000, };
static const unsigned int vsimcard_val_tbl[] = { 1800000, 2900000, };
static const unsigned int vvib_val_tbl[] = { 1300000, 1800000, 2000000,
3000000, };
static const unsigned int vusb_val_tbl[] = { 0, 3300000, };
static const unsigned int vaudio_val_tbl[] = { 0, 2775000, };
/**
* SoC specific configuration for omap4. The data below is comes from Motorola
* Linux kernel tree. It's basically the values of cpcap_regltr_data,
* cpcap_regulator_mode_values and cpcap_regulator_off_mode_values, see
* CPCAP_REG macro above.
*
* SW1 to SW4 and SW6 seems to be unused for mapphone. Note that VSIM and
* VSIMCARD have a shared resource assignment bit.
*/
static struct cpcap_regulator omap4_regulators[] = {
CPCAP_REG(SW1, CPCAP_REG_S1C1, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW1_SEL, unknown_val_tbl,
0, 0, 0, 0, 0, 0),
CPCAP_REG(SW2, CPCAP_REG_S2C1, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW2_SEL, unknown_val_tbl,
0, 0, 0, 0, 0, 0),
CPCAP_REG(SW3, CPCAP_REG_S3C, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW3_SEL, unknown_val_tbl,
0, 0, 0, 0, 0, 0),
CPCAP_REG(SW4, CPCAP_REG_S4C1, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW4_SEL, unknown_val_tbl,
0, 0, 0, 0, 0, 0),
CPCAP_REG(SW5, CPCAP_REG_S5C, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW5_SEL, sw5_val_tbl,
0x28, 0, 0, 0x20 | CPCAP_REG_OFF_MODE_SEC, 0, 0),
CPCAP_REG(SW6, CPCAP_REG_S6C, CPCAP_REG_ASSIGN2,
CPCAP_BIT_SW6_SEL, unknown_val_tbl,
0, 0, 0, 0, 0, 0),
CPCAP_REG(VCAM, CPCAP_REG_VCAMC, CPCAP_REG_ASSIGN2,
CPCAP_BIT_VCAM_SEL, vcam_val_tbl,
0x87, 0x30, 4, 0x3, 0, 420),
CPCAP_REG(VCSI, CPCAP_REG_VCSIC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VCSI_SEL, vcsi_val_tbl,
0x47, 0x10, 4, 0x43, 0x41, 350),
CPCAP_REG(VDAC, CPCAP_REG_VDACC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VDAC_SEL, vdac_val_tbl,
0x87, 0x30, 4, 0x3, 0, 420),
CPCAP_REG(VDIG, CPCAP_REG_VDIGC, CPCAP_REG_ASSIGN2,
CPCAP_BIT_VDIG_SEL, vdig_val_tbl,
0x87, 0x30, 4, 0x82, 0, 420),
CPCAP_REG(VFUSE, CPCAP_REG_VFUSEC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VFUSE_SEL, vfuse_val_tbl,
0x80, 0xf, 0, 0x80, 0, 420),
CPCAP_REG(VHVIO, CPCAP_REG_VHVIOC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VHVIO_SEL, vhvio_val_tbl,
0x17, 0, 0, 0, 0x12, 0),
CPCAP_REG(VSDIO, CPCAP_REG_VSDIOC, CPCAP_REG_ASSIGN2,
CPCAP_BIT_VSDIO_SEL, vsdio_val_tbl,
0x87, 0x38, 3, 0x82, 0, 420),
CPCAP_REG(VPLL, CPCAP_REG_VPLLC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VPLL_SEL, vpll_val_tbl,
0x43, 0x18, 3, 0x2, 0, 420),
CPCAP_REG(VRF1, CPCAP_REG_VRF1C, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VRF1_SEL, vrf1_val_tbl,
0xac, 0x2, 1, 0x4, 0, 10),
CPCAP_REG(VRF2, CPCAP_REG_VRF2C, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VRF2_SEL, vrf2_val_tbl,
0x23, 0x8, 3, 0, 0, 10),
CPCAP_REG(VRFREF, CPCAP_REG_VRFREFC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VRFREF_SEL, vrfref_val_tbl,
0x23, 0x8, 3, 0, 0, 420),
CPCAP_REG(VWLAN1, CPCAP_REG_VWLAN1C, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VWLAN1_SEL, vwlan1_val_tbl,
0x47, 0x10, 4, 0, 0, 420),
CPCAP_REG(VWLAN2, CPCAP_REG_VWLAN2C, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VWLAN2_SEL, vwlan2_val_tbl,
0x20c, 0xc0, 6, 0x20c, 0, 420),
CPCAP_REG(VSIM, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
0xffff, vsim_val_tbl,
0x23, 0x8, 3, 0x3, 0, 420),
CPCAP_REG(VSIMCARD, CPCAP_REG_VSIMC, CPCAP_REG_ASSIGN3,
0xffff, vsimcard_val_tbl,
0x1e80, 0x8, 3, 0x1e00, 0, 420),
CPCAP_REG(VVIB, CPCAP_REG_VVIBC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VVIB_SEL, vvib_val_tbl,
0x1, 0xc, 2, 0x1, 0, 500),
CPCAP_REG(VUSB, CPCAP_REG_VUSBC, CPCAP_REG_ASSIGN3,
CPCAP_BIT_VUSB_SEL, vusb_val_tbl,
0x11c, 0x40, 6, 0xc, 0, 0),
CPCAP_REG(VAUDIO, CPCAP_REG_VAUDIOC, CPCAP_REG_ASSIGN4,
CPCAP_BIT_VAUDIO_SEL, vaudio_val_tbl,
0x16, 0x1, 0, 0x4, 0, 0),
{ /* sentinel */ },
};
static const struct of_device_id cpcap_regulator_id_table[] = {
{
.compatible = "motorola,cpcap-regulator",
},
{
.compatible = "motorola,mapphone-cpcap-regulator",
.data = omap4_regulators,
},
{},
};
MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table);
static int cpcap_regulator_probe(struct platform_device *pdev)
{
struct cpcap_ddata *ddata;
const struct of_device_id *match;
struct regulator_config config;
struct regulator_init_data init_data;
int i;
match = of_match_device(of_match_ptr(cpcap_regulator_id_table),
&pdev->dev);
if (!match)
return -EINVAL;
if (!match->data) {
dev_err(&pdev->dev, "no configuration data found\n");
return -ENODEV;
}
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
if (!ddata->reg)
return -ENODEV;
ddata->dev = &pdev->dev;
ddata->soc = match->data;
platform_set_drvdata(pdev, ddata);
memset(&config, 0, sizeof(config));
memset(&init_data, 0, sizeof(init_data));
config.dev = &pdev->dev;
config.regmap = ddata->reg;
config.init_data = &init_data;
for (i = 0; i < CPCAP_NR_REGULATORS; i++) {
const struct cpcap_regulator *regulator = &ddata->soc[i];
struct regulator_dev *rdev;
if (!regulator->rdesc.name)
break;
if (regulator->rdesc.volt_table == unknown_val_tbl)
continue;
config.driver_data = (void *)regulator;
rdev = devm_regulator_register(&pdev->dev,
&regulator->rdesc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
regulator->rdesc.name);
return PTR_ERR(rdev);
}
}
return 0;
}
static struct platform_driver cpcap_regulator_driver = {
.probe = cpcap_regulator_probe,
.driver = {
.name = "cpcap-regulator",
.of_match_table = of_match_ptr(cpcap_regulator_id_table),
},
};
module_platform_driver(cpcap_regulator_driver);
MODULE_ALIAS("platform:cpcap-regulator");
MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("CPCAP regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -19,12 +19,6 @@
#include "internal.h"
enum {
NORMAL_GET,
EXCLUSIVE_GET,
OPTIONAL_GET,
};
static void devm_regulator_release(struct device *dev, void *res)
{
regulator_put(*(struct regulator **)res);
@ -39,20 +33,7 @@ static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
if (!ptr)
return ERR_PTR(-ENOMEM);
switch (get_type) {
case NORMAL_GET:
regulator = regulator_get(dev, id);
break;
case EXCLUSIVE_GET:
regulator = regulator_get_exclusive(dev, id);
break;
case OPTIONAL_GET:
regulator = regulator_get_optional(dev, id);
break;
default:
regulator = ERR_PTR(-EINVAL);
}
regulator = _regulator_get(dev, id, get_type);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
@ -139,6 +120,18 @@ void devm_regulator_put(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
struct regulator_bulk_devres {
struct regulator_bulk_data *consumers;
int num_consumers;
};
static void devm_regulator_bulk_release(struct device *dev, void *res)
{
struct regulator_bulk_devres *devres = res;
regulator_bulk_free(devres->num_consumers, devres->consumers);
}
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
@ -157,29 +150,22 @@ EXPORT_SYMBOL_GPL(devm_regulator_put);
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
struct regulator_bulk_devres *devres;
int ret;
for (i = 0; i < num_consumers; i++)
consumers[i].consumer = NULL;
devres = devres_alloc(devm_regulator_bulk_release,
sizeof(*devres), GFP_KERNEL);
if (!devres)
return -ENOMEM;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
consumers[i].consumer = NULL;
goto err;
ret = regulator_bulk_get(dev, num_consumers, consumers);
if (!ret) {
devres->consumers = consumers;
devres->num_consumers = num_consumers;
devres_add(dev, devres);
} else {
devres_free(devres);
}
}
return 0;
err:
for (i = 0; i < num_consumers && consumers[i].consumer; i++)
devm_regulator_put(consumers[i].consumer);
return ret;
}

View File

@ -202,7 +202,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
}
static struct regulator_ops fan53555_regulator_ops = {
static const struct regulator_ops fan53555_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,

View File

@ -96,7 +96,7 @@ static int hi655x_disable(struct regulator_dev *rdev)
return ret;
}
static struct regulator_ops hi655x_regulator_ops = {
static const struct regulator_ops hi655x_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = hi655x_disable,
.is_enabled = hi655x_is_enabled,
@ -105,7 +105,7 @@ static struct regulator_ops hi655x_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static struct regulator_ops hi655x_ldo_linear_ops = {
static const struct regulator_ops hi655x_ldo_linear_ops = {
.enable = regulator_enable_regmap,
.disable = hi655x_disable,
.is_enabled = hi655x_is_enabled,

View File

@ -51,4 +51,14 @@ regulator_of_get_init_data(struct device *dev,
}
#endif
enum regulator_get_type {
NORMAL_GET,
EXCLUSIVE_GET,
OPTIONAL_GET,
MAX_GET_TYPE
};
struct regulator *_regulator_get(struct device *dev, const char *id,
enum regulator_get_type get_type);
#endif

View File

@ -227,7 +227,7 @@ err_i2c:
return ret;
}
static struct regulator_ops lp8755_buck_ops = {
static const struct regulator_ops lp8755_buck_ops = {
.map_voltage = regulator_map_voltage_linear,
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,

View File

@ -161,7 +161,7 @@ static int ltc3589_set_suspend_mode(struct regulator_dev *rdev,
}
/* SW1, SW2, SW3, LDO2 */
static struct regulator_ops ltc3589_linear_regulator_ops = {
static const struct regulator_ops ltc3589_linear_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -175,18 +175,18 @@ static struct regulator_ops ltc3589_linear_regulator_ops = {
};
/* BB_OUT, LDO3 */
static struct regulator_ops ltc3589_fixed_regulator_ops = {
static const struct regulator_ops ltc3589_fixed_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
/* LDO1 */
static struct regulator_ops ltc3589_fixed_standby_regulator_ops = {
static const struct regulator_ops ltc3589_fixed_standby_regulator_ops = {
};
/* LDO4 */
static struct regulator_ops ltc3589_table_regulator_ops = {
static const struct regulator_ops ltc3589_table_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -161,7 +161,7 @@ static int ltc3676_of_parse_cb(struct device_node *np,
}
/* SW1, SW2, SW3, SW4 linear 0.8V-3.3V with scalar via R1/R2 feeback res */
static struct regulator_ops ltc3676_linear_regulator_ops = {
static const struct regulator_ops ltc3676_linear_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -173,11 +173,11 @@ static struct regulator_ops ltc3676_linear_regulator_ops = {
};
/* LDO1 always on fixed 0.8V-3.3V via scalar via R1/R2 feeback res */
static struct regulator_ops ltc3676_fixed_standby_regulator_ops = {
static const struct regulator_ops ltc3676_fixed_standby_regulator_ops = {
};
/* LDO2, LDO3 fixed (LDO2 has external scalar via R1/R2 feedback res) */
static struct regulator_ops ltc3676_fixed_regulator_ops = {
static const struct regulator_ops ltc3676_fixed_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -85,14 +85,14 @@ static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
reg_data);
}
static struct regulator_ops max14577_safeout_ops = {
static const struct regulator_ops max14577_safeout_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops max14577_charger_ops = {
static const struct regulator_ops max14577_charger_ops = {
.is_enabled = max14577_reg_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -130,7 +130,7 @@ static const struct regulator_desc max14577_supported_regulators[] = {
[MAX14577_CHARGER] = MAX14577_CHARGER_REG,
};
static struct regulator_ops max77836_ldo_ops = {
static const struct regulator_ops max77836_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,

View File

@ -644,7 +644,7 @@ static int max77620_of_parse_cb(struct device_node *np,
return max77620_init_pmic(pmic, desc->id);
}
static struct regulator_ops max77620_regulator_ops = {
static const struct regulator_ops max77620_regulator_ops = {
.is_enabled = max77620_regulator_is_enabled,
.enable = max77620_regulator_enable,
.disable = max77620_regulator_disable,

View File

@ -289,7 +289,7 @@ static int max77686_of_parse_cb(struct device_node *np,
return 0;
}
static struct regulator_ops max77686_ops = {
static const struct regulator_ops max77686_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -301,7 +301,7 @@ static struct regulator_ops max77686_ops = {
.set_suspend_mode = max77686_set_suspend_mode,
};
static struct regulator_ops max77686_ldo_ops = {
static const struct regulator_ops max77686_ldo_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -314,7 +314,7 @@ static struct regulator_ops max77686_ldo_ops = {
.set_suspend_disable = max77686_set_suspend_disable,
};
static struct regulator_ops max77686_buck1_ops = {
static const struct regulator_ops max77686_buck1_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -326,7 +326,7 @@ static struct regulator_ops max77686_buck1_ops = {
.set_suspend_disable = max77686_set_suspend_disable,
};
static struct regulator_ops max77686_buck_dvs_ops = {
static const struct regulator_ops max77686_buck_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -141,7 +141,7 @@ static const unsigned int max77693_safeout_table[] = {
3300000,
};
static struct regulator_ops max77693_safeout_ops = {
static const struct regulator_ops max77693_safeout_ops = {
.list_voltage = regulator_list_voltage_table,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,

View File

@ -288,7 +288,7 @@ static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev,
/*
* LDOs 2, 4-19, 22-35
*/
static struct regulator_ops max77802_ldo_ops_logic1 = {
static const struct regulator_ops max77802_ldo_ops_logic1 = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -304,7 +304,7 @@ static struct regulator_ops max77802_ldo_ops_logic1 = {
/*
* LDOs 1, 20, 21, 3
*/
static struct regulator_ops max77802_ldo_ops_logic2 = {
static const struct regulator_ops max77802_ldo_ops_logic2 = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -319,7 +319,7 @@ static struct regulator_ops max77802_ldo_ops_logic2 = {
};
/* BUCKS 1, 6 */
static struct regulator_ops max77802_buck_16_dvs_ops = {
static const struct regulator_ops max77802_buck_16_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -333,7 +333,7 @@ static struct regulator_ops max77802_buck_16_dvs_ops = {
};
/* BUCKs 2-4 */
static struct regulator_ops max77802_buck_234_ops = {
static const struct regulator_ops max77802_buck_234_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
@ -348,7 +348,7 @@ static struct regulator_ops max77802_buck_234_ops = {
};
/* BUCKs 5, 7-10 */
static struct regulator_ops max77802_buck_dvs_ops = {
static const struct regulator_ops max77802_buck_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -109,7 +109,7 @@ struct max8907_regulator {
#define LDO_650_25(id, supply, base) REG_LDO(id, supply, (base), \
650000, 2225000, 25000)
static struct regulator_ops max8907_mbatt_ops = {
static const struct regulator_ops max8907_mbatt_ops = {
};
static struct regulator_ops max8907_ldo_ops = {
@ -121,13 +121,13 @@ static struct regulator_ops max8907_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops max8907_ldo_hwctl_ops = {
static const struct regulator_ops max8907_ldo_hwctl_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static struct regulator_ops max8907_fixed_ops = {
static const struct regulator_ops max8907_fixed_ops = {
.list_voltage = regulator_list_voltage_linear,
};
@ -138,11 +138,11 @@ static struct regulator_ops max8907_out5v_ops = {
.is_enabled = regulator_is_enabled_regmap,
};
static struct regulator_ops max8907_out5v_hwctl_ops = {
static const struct regulator_ops max8907_out5v_hwctl_ops = {
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops max8907_bbat_ops = {
static const struct regulator_ops max8907_bbat_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,

View File

@ -132,7 +132,7 @@ static int max8925_set_dvm_disable(struct regulator_dev *rdev)
return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
}
static struct regulator_ops max8925_regulator_sdv_ops = {
static const struct regulator_ops max8925_regulator_sdv_ops = {
.map_voltage = regulator_map_voltage_linear,
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = max8925_set_voltage_sel,
@ -145,7 +145,7 @@ static struct regulator_ops max8925_regulator_sdv_ops = {
.set_suspend_disable = max8925_set_dvm_disable,
};
static struct regulator_ops max8925_regulator_ldo_ops = {
static const struct regulator_ops max8925_regulator_ldo_ops = {
.map_voltage = regulator_map_voltage_linear,
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = max8925_set_voltage_sel,

View File

@ -113,7 +113,7 @@ static int max8952_set_voltage_sel(struct regulator_dev *rdev,
return 0;
}
static struct regulator_ops max8952_ops = {
static const struct regulator_ops max8952_ops = {
.list_voltage = max8952_list_voltage,
.get_voltage_sel = max8952_get_voltage_sel,
.set_voltage_sel = max8952_set_voltage_sel,

View File

@ -528,7 +528,7 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
return ret;
}
static struct regulator_ops palmas_ops_smps = {
static const struct regulator_ops palmas_ops_smps = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -542,7 +542,7 @@ static struct regulator_ops palmas_ops_smps = {
.set_ramp_delay = palmas_smps_set_ramp_delay,
};
static struct regulator_ops palmas_ops_ext_control_smps = {
static const struct regulator_ops palmas_ops_ext_control_smps = {
.set_mode = palmas_set_mode_smps,
.get_mode = palmas_get_mode_smps,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -553,7 +553,7 @@ static struct regulator_ops palmas_ops_ext_control_smps = {
.set_ramp_delay = palmas_smps_set_ramp_delay,
};
static struct regulator_ops palmas_ops_smps10 = {
static const struct regulator_ops palmas_ops_smps10 = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -565,7 +565,7 @@ static struct regulator_ops palmas_ops_smps10 = {
.get_bypass = regulator_get_bypass_regmap,
};
static struct regulator_ops tps65917_ops_smps = {
static const struct regulator_ops tps65917_ops_smps = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -578,7 +578,7 @@ static struct regulator_ops tps65917_ops_smps = {
.set_voltage_time_sel = regulator_set_voltage_time_sel,
};
static struct regulator_ops tps65917_ops_ext_control_smps = {
static const struct regulator_ops tps65917_ops_ext_control_smps = {
.set_mode = palmas_set_mode_smps,
.get_mode = palmas_get_mode_smps,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -602,7 +602,7 @@ static int palmas_is_enabled_ldo(struct regulator_dev *dev)
return !!(reg);
}
static struct regulator_ops palmas_ops_ldo = {
static const struct regulator_ops palmas_ops_ldo = {
.is_enabled = palmas_is_enabled_ldo,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -612,7 +612,7 @@ static struct regulator_ops palmas_ops_ldo = {
.map_voltage = regulator_map_voltage_linear,
};
static struct regulator_ops palmas_ops_ldo9 = {
static const struct regulator_ops palmas_ops_ldo9 = {
.is_enabled = palmas_is_enabled_ldo,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -624,23 +624,23 @@ static struct regulator_ops palmas_ops_ldo9 = {
.get_bypass = regulator_get_bypass_regmap,
};
static struct regulator_ops palmas_ops_ext_control_ldo = {
static const struct regulator_ops palmas_ops_ext_control_ldo = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
};
static struct regulator_ops palmas_ops_extreg = {
static const struct regulator_ops palmas_ops_extreg = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static struct regulator_ops palmas_ops_ext_control_extreg = {
static const struct regulator_ops palmas_ops_ext_control_extreg = {
};
static struct regulator_ops tps65917_ops_ldo = {
static const struct regulator_ops tps65917_ops_ldo = {
.is_enabled = palmas_is_enabled_ldo,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -651,7 +651,7 @@ static struct regulator_ops tps65917_ops_ldo = {
.set_voltage_time_sel = regulator_set_voltage_time_sel,
};
static struct regulator_ops tps65917_ops_ldo_1_2 = {
static const struct regulator_ops tps65917_ops_ldo_1_2 = {
.is_enabled = palmas_is_enabled_ldo,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,

View File

@ -54,7 +54,7 @@ static const unsigned int pbias_volt_table[] = {
3000000
};
static struct regulator_ops pbias_regulator_voltage_ops = {
static const struct regulator_ops pbias_regulator_voltage_ops = {
.list_voltage = regulator_list_voltage_table,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,

View File

@ -210,7 +210,7 @@ static int pcap_regulator_is_enabled(struct regulator_dev *rdev)
return (tmp >> vreg->en) & 1;
}
static struct regulator_ops pcap_regulator_ops = {
static const struct regulator_ops pcap_regulator_ops = {
.list_voltage = regulator_list_voltage_table,
.set_voltage_sel = pcap_regulator_set_voltage_sel,
.get_voltage_sel = pcap_regulator_get_voltage_sel,

View File

@ -41,7 +41,7 @@
.enable_mask = PCF50633_REGULATOR_ON, \
}
static struct regulator_ops pcf50633_regulator_ops = {
static const struct regulator_ops pcf50633_regulator_ops = {
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,

View File

@ -126,7 +126,7 @@ static int pfuze100_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
return ret;
}
static struct regulator_ops pfuze100_ldo_regulator_ops = {
static const struct regulator_ops pfuze100_ldo_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@ -135,14 +135,14 @@ static struct regulator_ops pfuze100_ldo_regulator_ops = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
};
static struct regulator_ops pfuze100_fixed_regulator_ops = {
static const struct regulator_ops pfuze100_fixed_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops pfuze100_sw_regulator_ops = {
static const struct regulator_ops pfuze100_sw_regulator_ops = {
.list_voltage = regulator_list_voltage_linear,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
@ -150,7 +150,7 @@ static struct regulator_ops pfuze100_sw_regulator_ops = {
.set_ramp_delay = pfuze100_set_ramp_delay,
};
static struct regulator_ops pfuze100_swb_regulator_ops = {
static const struct regulator_ops pfuze100_swb_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_table,

View File

@ -162,7 +162,7 @@ static int pv88060_get_current_limit(struct regulator_dev *rdev)
return info->current_limits[data];
}
static struct regulator_ops pv88060_buck_ops = {
static const struct regulator_ops pv88060_buck_ops = {
.get_mode = pv88060_buck_get_mode,
.set_mode = pv88060_buck_set_mode,
.enable = regulator_enable_regmap,
@ -175,7 +175,7 @@ static struct regulator_ops pv88060_buck_ops = {
.get_current_limit = pv88060_get_current_limit,
};
static struct regulator_ops pv88060_ldo_ops = {
static const struct regulator_ops pv88060_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -306,7 +306,7 @@ static int pv88080_get_current_limit(struct regulator_dev *rdev)
return info->current_limits[data];
}
static struct regulator_ops pv88080_buck_ops = {
static const struct regulator_ops pv88080_buck_ops = {
.get_mode = pv88080_buck_get_mode,
.set_mode = pv88080_buck_set_mode,
.enable = regulator_enable_regmap,
@ -319,7 +319,7 @@ static struct regulator_ops pv88080_buck_ops = {
.get_current_limit = pv88080_get_current_limit,
};
static struct regulator_ops pv88080_hvbuck_ops = {
static const struct regulator_ops pv88080_hvbuck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -184,7 +184,7 @@ static int pv88090_get_current_limit(struct regulator_dev *rdev)
return info->current_limits[data];
}
static struct regulator_ops pv88090_buck_ops = {
static const struct regulator_ops pv88090_buck_ops = {
.get_mode = pv88090_buck_get_mode,
.set_mode = pv88090_buck_set_mode,
.enable = regulator_enable_regmap,
@ -197,7 +197,7 @@ static struct regulator_ops pv88090_buck_ops = {
.get_current_limit = pv88090_get_current_limit,
};
static struct regulator_ops pv88090_ldo_ops = {
static const struct regulator_ops pv88090_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -305,6 +305,56 @@ static const struct regulator_desc pm8916_buck_hvo_smps = {
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8994_hfsmps = {
.linear_ranges = (struct regulator_linear_range[]) {
REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500),
REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000),
},
.n_linear_ranges = 2,
.n_voltages = 159,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8994_ftsmps = {
.linear_ranges = (struct regulator_linear_range[]) {
REGULATOR_LINEAR_RANGE(350000, 0, 199, 5000),
REGULATOR_LINEAR_RANGE(700000, 200, 349, 10000),
},
.n_linear_ranges = 2,
.n_voltages = 350,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8994_nldo = {
.linear_ranges = (struct regulator_linear_range[]) {
REGULATOR_LINEAR_RANGE(750000, 0, 63, 12500),
},
.n_linear_ranges = 1,
.n_voltages = 64,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8994_pldo = {
.linear_ranges = (struct regulator_linear_range[]) {
REGULATOR_LINEAR_RANGE( 750000, 0, 63, 12500),
REGULATOR_LINEAR_RANGE(1550000, 64, 126, 25000),
REGULATOR_LINEAR_RANGE(3100000, 127, 163, 50000),
},
.n_linear_ranges = 3,
.n_voltages = 164,
.ops = &rpm_smps_ldo_ops,
};
static const struct regulator_desc pm8994_switch = {
.ops = &rpm_switch_ops,
};
static const struct regulator_desc pm8994_lnldo = {
.fixed_uV = 1740000,
.n_voltages = 1,
.ops = &rpm_smps_ldo_ops_fixed,
};
struct rpm_regulator_data {
const char *name;
u32 type;
@ -443,10 +493,62 @@ static const struct rpm_regulator_data rpm_pma8084_regulators[] = {
{}
};
static const struct rpm_regulator_data rpm_pm8994_regulators[] = {
{ "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_ftsmps, "vdd_s1" },
{ "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_ftsmps, "vdd_s2" },
{ "s3", QCOM_SMD_RPM_SMPA, 3, &pm8994_hfsmps, "vdd_s3" },
{ "s4", QCOM_SMD_RPM_SMPA, 4, &pm8994_hfsmps, "vdd_s4" },
{ "s5", QCOM_SMD_RPM_SMPA, 5, &pm8994_hfsmps, "vdd_s5" },
{ "s6", QCOM_SMD_RPM_SMPA, 6, &pm8994_ftsmps, "vdd_s6" },
{ "s7", QCOM_SMD_RPM_SMPA, 7, &pm8994_hfsmps, "vdd_s7" },
{ "s8", QCOM_SMD_RPM_SMPA, 8, &pm8994_ftsmps, "vdd_s8" },
{ "s9", QCOM_SMD_RPM_SMPA, 9, &pm8994_ftsmps, "vdd_s9" },
{ "s10", QCOM_SMD_RPM_SMPA, 10, &pm8994_ftsmps, "vdd_s10" },
{ "s11", QCOM_SMD_RPM_SMPA, 11, &pm8994_ftsmps, "vdd_s11" },
{ "s12", QCOM_SMD_RPM_SMPA, 12, &pm8994_ftsmps, "vdd_s12" },
{ "l1", QCOM_SMD_RPM_LDOA, 1, &pm8994_nldo, "vdd_l1" },
{ "l2", QCOM_SMD_RPM_LDOA, 2, &pm8994_nldo, "vdd_l2_l26_l28" },
{ "l3", QCOM_SMD_RPM_LDOA, 3, &pm8994_nldo, "vdd_l3_l11" },
{ "l4", QCOM_SMD_RPM_LDOA, 4, &pm8994_nldo, "vdd_l4_l27_l31" },
{ "l5", QCOM_SMD_RPM_LDOA, 5, &pm8994_lnldo, "vdd_l5_l7" },
{ "l6", QCOM_SMD_RPM_LDOA, 6, &pm8994_pldo, "vdd_l6_l12_l32" },
{ "l7", QCOM_SMD_RPM_LDOA, 7, &pm8994_lnldo, "vdd_l5_l7" },
{ "l8", QCOM_SMD_RPM_LDOA, 8, &pm8994_pldo, "vdd_l8_l16_l30" },
{ "l9", QCOM_SMD_RPM_LDOA, 9, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
{ "l10", QCOM_SMD_RPM_LDOA, 10, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
{ "l11", QCOM_SMD_RPM_LDOA, 11, &pm8994_nldo, "vdd_l3_l11" },
{ "l12", QCOM_SMD_RPM_LDOA, 12, &pm8994_pldo, "vdd_l6_l12_l32" },
{ "l13", QCOM_SMD_RPM_LDOA, 13, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
{ "l14", QCOM_SMD_RPM_LDOA, 14, &pm8994_pldo, "vdd_l14_l15" },
{ "l15", QCOM_SMD_RPM_LDOA, 15, &pm8994_pldo, "vdd_l14_l15" },
{ "l16", QCOM_SMD_RPM_LDOA, 16, &pm8994_pldo, "vdd_l8_l16_l30" },
{ "l17", QCOM_SMD_RPM_LDOA, 17, &pm8994_pldo, "vdd_l17_l29" },
{ "l18", QCOM_SMD_RPM_LDOA, 18, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
{ "l19", QCOM_SMD_RPM_LDOA, 19, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
{ "l20", QCOM_SMD_RPM_LDOA, 20, &pm8994_pldo, "vdd_l20_l21" },
{ "l21", QCOM_SMD_RPM_LDOA, 21, &pm8994_pldo, "vdd_l20_l21" },
{ "l22", QCOM_SMD_RPM_LDOA, 22, &pm8994_pldo, "vdd_l9_l10_l18_l22" },
{ "l23", QCOM_SMD_RPM_LDOA, 23, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
{ "l24", QCOM_SMD_RPM_LDOA, 24, &pm8994_pldo, "vdd_l13_l19_l23_l24" },
{ "l25", QCOM_SMD_RPM_LDOA, 25, &pm8994_pldo, "vdd_l25" },
{ "l26", QCOM_SMD_RPM_LDOA, 26, &pm8994_nldo, "vdd_l2_l26_l28" },
{ "l27", QCOM_SMD_RPM_LDOA, 27, &pm8994_nldo, "vdd_l4_l27_l31" },
{ "l28", QCOM_SMD_RPM_LDOA, 28, &pm8994_nldo, "vdd_l2_l26_l28" },
{ "l29", QCOM_SMD_RPM_LDOA, 29, &pm8994_pldo, "vdd_l17_l29" },
{ "l30", QCOM_SMD_RPM_LDOA, 30, &pm8994_pldo, "vdd_l8_l16_l30" },
{ "l31", QCOM_SMD_RPM_LDOA, 31, &pm8994_nldo, "vdd_l4_l27_l31" },
{ "l32", QCOM_SMD_RPM_LDOA, 32, &pm8994_pldo, "vdd_l6_l12_l32" },
{ "lvs1", QCOM_SMD_RPM_VSA, 1, &pm8994_switch, "vdd_lvs1_2" },
{ "lvs2", QCOM_SMD_RPM_VSA, 2, &pm8994_switch, "vdd_lvs1_2" },
{}
};
static const struct of_device_id rpm_of_match[] = {
{ .compatible = "qcom,rpm-pm8841-regulators", .data = &rpm_pm8841_regulators },
{ .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators },
{ .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators },
{ .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators },
{ .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators },
{}
};

View File

@ -61,7 +61,7 @@ static int rc5t583_regulator_enable_time(struct regulator_dev *rdev)
return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us);
}
static struct regulator_ops rc5t583_ops = {
static const struct regulator_ops rc5t583_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,

View File

@ -19,7 +19,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
static struct regulator_ops rn5t618_reg_ops = {
static const struct regulator_ops rn5t618_reg_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,

View File

@ -26,6 +26,7 @@
#define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators)
struct s2mpa01_info {
struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX];
int ramp_delay24;
int ramp_delay3;
int ramp_delay5;
@ -341,9 +342,9 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
{
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX] = { };
struct device_node *reg_np = NULL;
struct regulator_config config = { };
struct of_regulator_match *rdata;
struct s2mpa01_info *s2mpa01;
int i;
@ -351,6 +352,7 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
if (!s2mpa01)
return -ENOMEM;
rdata = s2mpa01->rdata;
for (i = 0; i < S2MPA01_REGULATOR_CNT; i++)
rdata[i].name = regulators[i].name;

View File

@ -157,19 +157,19 @@ static struct tps65086_regulator regulators[] = {
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swa2", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swa3", SWB2, TPS65086_SWVTT_EN, BIT(7)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
};
static int tps65086_of_parse_cb(struct device_node *dev,
static int tps65086_of_parse_cb(struct device_node *node,
const struct regulator_desc *desc,
struct regulator_config *config)
{
int ret;
/* Check for 25mV step mode */
if (of_property_read_bool(config->of_node, "ti,regulator-step-size-25mv")) {
if (of_property_read_bool(node, "ti,regulator-step-size-25mv")) {
switch (desc->id) {
case BUCK1:
case BUCK2:
@ -193,7 +193,7 @@ static int tps65086_of_parse_cb(struct device_node *dev,
}
/* Check for decay mode */
if (desc->id <= BUCK6 && of_property_read_bool(config->of_node, "ti,regulator-decay")) {
if (desc->id <= BUCK6 && of_property_read_bool(node, "ti,regulator-decay")) {
ret = regmap_write_bits(config->regmap,
regulators[desc->id].decay_reg,
regulators[desc->id].decay_mask,

View File

@ -179,7 +179,8 @@ static const struct regulator_desc regulators[] = {
TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1",
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1,
TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN,
NULL, tps65217_uv1_ranges, 2, TPS65217_REG_SEQ1,
NULL, tps65217_uv1_ranges,
ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ1,
TPS65217_SEQ1_DC1_SEQ_MASK),
TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2",
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2,
@ -190,7 +191,8 @@ static const struct regulator_desc regulators[] = {
TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3",
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3,
TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN,
NULL, tps65217_uv1_ranges, 1, TPS65217_REG_SEQ2,
NULL, tps65217_uv1_ranges,
ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ2,
TPS65217_SEQ2_DC3_SEQ_MASK),
TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1",
tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1,