diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 17:23:57 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-20 17:23:57 -0800 |
| commit | f790bd9c8e826434ab6c326b225276ed0f73affe (patch) | |
| tree | 58c7f3c0d5bf1cd2131592219178d0e57b3afd1a | |
| parent | b3de5ad688f0f52457e73767f95a640ab4158d0d (diff) | |
| parent | fad9cd45edf558b5886219d58986a88a83926bbf (diff) | |
| download | linux-f790bd9c8e826434ab6c326b225276ed0f73affe.tar.gz linux-f790bd9c8e826434ab6c326b225276ed0f73affe.tar.bz2 linux-f790bd9c8e826434ab6c326b225276ed0f73affe.zip | |
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
...
48 files changed, 910 insertions, 204 deletions
diff --git a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt index 37c4ea076f88..1d58c8cfdbc0 100644 --- a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt @@ -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. diff --git a/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt b/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt new file mode 100644 index 000000000000..675f4437ce92 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/cpcap-regulator.txt @@ -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; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt index e5cac1e0ca8a..dd1ed789728e 100644 --- a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt @@ -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. diff --git a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt index 1f8d6f84b657..4e3dfb5b5f16 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.txt @@ -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: @@ -80,6 +81,56 @@ Regulator nodes are identified by their compatible: - 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: +- 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_l11-supply: - vdd_l2_l3_l4_l27-supply: - vdd_l5_l7-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, diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index a62a89674fb5..89bbd6e8bad1 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -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, diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index b100a63ff3b3..fd86446e499b 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -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, diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 936f7ccc9736..be06eb29c681 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -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 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 14294692beb9..ef7725e2592a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -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 diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index 9dfabda8f478..afc5b5900181 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -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, diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c index 441864b9fece..43fda8b4455a 100644 --- a/drivers/regulator/act8945a-regulator.c +++ b/drivers/regulator/act8945a-regulator.c @@ -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, diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c index 8b0f788a9bbb..11c1f880b7bb 100644 --- a/drivers/regulator/ad5398.c +++ b/drivers/regulator/ad5398.c @@ -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, diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3a6d0290c54c..b041f277a38b 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -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 */ diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 302b57cb89c6..e76d094591e7 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -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, diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index fcb98dbda837..22bd71407622 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -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, diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index c0e93b1332f7..874d415d6b4f 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -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, diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index a3ade9e4ef47..0b9d4e3e52c7 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -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, diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 76b01835dcb4..9dd715407b39 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -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, diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 04baac9a165b..53d4fc70dbd0 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -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(®ulator_list_mutex); - return map->regulator; + r = map->regulator; + break; } } mutex_unlock(®ulator_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, |
