From 126187dafd221d672abc2c9839453023b884b5c9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 30 Apr 2015 15:38:59 +0530 Subject: [PATCH 1/8] regulator: Fix spelling error in bindings Minor spell fix, s/intialised/initialised. Signed-off-by: Viresh Kumar Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index abb26b58c83e..606391bea89b 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -13,7 +13,7 @@ Optional properties: - -supply: phandle to the parent supply/regulator node - regulator-ramp-delay: ramp delay for regulator(in uV/uS) For hardware which supports disabling ramp rate, it should be explicitly - intialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay. + initialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay. - regulator-enable-ramp-delay: The time taken, in microseconds, for the supply rail to reach the target voltage, plus/minus whatever tolerance the board design requires. This property describes the total system ramp time From 9eac5fdfabc67603fcdc5b59079ff6da90e17a16 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 May 2015 18:32:32 +0200 Subject: [PATCH 2/8] regulator: Allow compile test of GPIO consumers if !GPIOLIB The GPIO subsystem provides dummy GPIO consumer functions if GPIOLIB is not enabled. Hence drivers that depend on GPIOLIB, but use GPIO consumer functionality only, can still be compiled if GPIOLIB is not enabled. Relax the dependency on GPIOLIB if COMPILE_TEST is enabled, where appropriate. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index a6f116aa5235..91aa2302b74a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -233,7 +233,7 @@ config REGULATOR_FAN53555 config REGULATOR_GPIO tristate "GPIO regulator support" - depends on GPIOLIB + depends on GPIOLIB || COMPILE_TEST help This driver provides support for regulators that can be controlled via gpios. From fda87a4283cf45f33d6a4eae645f6f3238e0e5dd Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 26 May 2015 18:19:45 +0200 Subject: [PATCH 3/8] regulator: fan53555: fill set_voltage_time_set callback Setting the set_voltage_time_sel callback to the standard function regulator_set_voltage_time_sel enables the regulator to actually honor ramp-delays when during regulator_set_voltage calls. Signed-off-by: Heiko Stuebner Signed-off-by: Mark Brown --- drivers/regulator/fan53555.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 3c25db89a021..42865681c00b 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -182,6 +182,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) static 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, .map_voltage = regulator_map_voltage_linear, .list_voltage = regulator_list_voltage_linear, .set_suspend_voltage = fan53555_set_suspend_voltage, From d87aef9164a57527f2ac36c226a4e60b20695656 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 31 May 2015 12:27:38 +0800 Subject: [PATCH 4/8] regulator: da9063: Fix up irq leak Current code does not set regulators->irq_ldo_lim and regulators->irq_uvov, so it actually calls free_irq(0, regulators) twice in remove() but does not free the irq actually used. Convert to use devm_request_threaded_irq instead and then we don't need to take care the clean up irq so remove irq_ldo_lim and irq_uvov from struct da9063_regulators. Note, regulators->irq_uvov is not used at all in current code. There is a slightly change in this patch, it will return error in probe() if devm_request_threaded_irq fails. If the irq is optional, it should be fine to allow platform_get_irq_byname fails. But current code does not allow platform_get_irq_byname fails. So I think the reason to allow request irq failure is just because the irq leak. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/da9063-regulator.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 31c2c593ae0b..aed1ad3dc964 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -117,9 +117,6 @@ struct da9063_regulator { /* Encapsulates all information for the regulators driver */ struct da9063_regulators { - int irq_ldo_lim; - int irq_uvov; - unsigned n_regulators; /* Array size to be defined during init. Keep at end. */ struct da9063_regulator regulator[0]; @@ -867,35 +864,23 @@ static int da9063_regulator_probe(struct platform_device *pdev) return irq; } - ret = request_threaded_irq(irq, + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, da9063_ldo_lim_event, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "LDO_LIM", regulators); if (ret) { - dev_err(&pdev->dev, - "Failed to request LDO_LIM IRQ.\n"); - regulators->irq_ldo_lim = -ENXIO; + dev_err(&pdev->dev, "Failed to request LDO_LIM IRQ.\n"); + return ret; } return 0; } -static int da9063_regulator_remove(struct platform_device *pdev) -{ - struct da9063_regulators *regulators = platform_get_drvdata(pdev); - - free_irq(regulators->irq_ldo_lim, regulators); - free_irq(regulators->irq_uvov, regulators); - - return 0; -} - static struct platform_driver da9063_regulator_driver = { .driver = { .name = DA9063_DRVNAME_REGULATORS, }, .probe = da9063_regulator_probe, - .remove = da9063_regulator_remove, }; static int __init da9063_regulator_init(void) From 22a10bca280073f81e9e2d9fed6f90a3bcf00236 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 11 Jun 2015 17:37:03 -0700 Subject: [PATCH 5/8] regulator: Add system_load constraint Some regulators have a fixed load that isn't captured by consumers that the kernel knows about. Add a constraint to support this. Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.txt | 2 ++ drivers/regulator/core.c | 2 ++ drivers/regulator/of_regulator.c | 3 +++ include/linux/regulator/machine.h | 3 +++ 4 files changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index abb26b58c83e..553d2d0fe6d9 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -37,6 +37,8 @@ Optional properties: - regulator-initial-mode: initial operating mode. The set of possible operating modes depends on the capabilities of every hardware so each device binding documentation explains which values the regulator supports. +- regulator-system-load: Load in uA present on regulator that is not captured by + any consumer request. Deprecated properties: - regulator-compatible: If a regulator chip contains multiple diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 443eaab933fc..c8d5e2b05fdf 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -678,6 +678,8 @@ static int drms_uA_update(struct regulator_dev *rdev) list_for_each_entry(sibling, &rdev->consumer_list, list) current_uA += sibling->uA_load; + current_uA += rdev->constraints->system_load; + if (rdev->desc->ops->set_load) { /* set the optimum mode for our new total regulator load */ err = rdev->desc->ops->set_load(rdev, current_uA); diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 24e812c48d93..482a86f90839 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -95,6 +95,9 @@ static void of_get_regulation_constraints(struct device_node *np, } } + if (!of_property_read_u32(np, "regulator-system-load", &pval)) + constraints->system_load = pval; + for (i = 0; i < ARRAY_SIZE(regulator_states); i++) { switch (i) { case PM_SUSPEND_MEM: diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index b07562e082c4..01526559c8c3 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -75,6 +75,7 @@ struct regulator_state { * * @min_uA: Smallest current consumers may set. * @max_uA: Largest current consumers may set. + * @system_load: Load that isn't captured by any consumer requests. * * @valid_modes_mask: Mask of modes which may be configured by consumers. * @valid_ops_mask: Operations which may be performed by consumers. @@ -112,6 +113,8 @@ struct regulation_constraints { int min_uA; int max_uA; + int system_load; + /* valid regulator operating modes for this machine */ unsigned int valid_modes_mask; From 23c779b9f9161d6568d3b2fca06e70ad182c480c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 11 Jun 2015 17:37:04 -0700 Subject: [PATCH 6/8] regulator: Add pull down support Some regulators need to be configured to pull down a resistor when the regulator is disabled. Add an op (set_pull_down) and a DT property + constraint to support this. Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.txt | 1 + drivers/regulator/core.c | 8 ++++++++ drivers/regulator/of_regulator.c | 2 ++ include/linux/regulator/driver.h | 5 +++++ include/linux/regulator/machine.h | 2 ++ 5 files changed, 18 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 553d2d0fe6d9..6c79fd70ab5a 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -39,6 +39,7 @@ Optional properties: documentation explains which values the regulator supports. - regulator-system-load: Load in uA present on regulator that is not captured by any consumer request. +- regulator-pull-down: Enable pull down resistor when the regulator is disabled. Deprecated properties: - regulator-compatible: If a regulator chip contains multiple diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index c8d5e2b05fdf..60fcfba52592 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1051,6 +1051,14 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } + if (rdev->constraints->pull_down && ops->set_pull_down) { + ret = ops->set_pull_down(rdev); + if (ret < 0) { + rdev_err(rdev, "failed to set pull down\n"); + goto out; + } + } + print_constraints(rdev); return 0; out: diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 482a86f90839..c3433db0acda 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -67,6 +67,8 @@ static void of_get_regulation_constraints(struct device_node *np, if (!constraints->always_on) /* status change should be possible. */ constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; + constraints->pull_down = of_property_read_bool(np, "regulator-pull-down"); + if (of_property_read_bool(np, "regulator-allow-bypass")) constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index fffa688ac3a7..76144a337ff7 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -121,6 +121,9 @@ struct regulator_linear_range { * @set_suspend_mode: Set the operating mode for the regulator when the * system is suspended. * + * @set_pull_down: Configure the regulator to pull down when the regulator + * is disabled. + * * This struct describes regulator operations which can be implemented by * regulator chip drivers. */ @@ -187,6 +190,8 @@ struct regulator_ops { /* set regulator suspend operating mode (defined in consumer.h) */ int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode); + + int (*set_pull_down) (struct regulator_dev *); }; /* diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 01526559c8c3..8ffb0619a03c 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -87,6 +87,7 @@ struct regulator_state { * applied. * @apply_uV: Apply the voltage constraint when initialising. * @ramp_disable: Disable ramp delay when initialising or when setting voltage. + * @pull_down: Enable pull down when regulator is disabled. * * @input_uV: Input voltage for regulator when supplied by another regulator. * @@ -141,6 +142,7 @@ struct regulation_constraints { unsigned boot_on:1; /* bootloader/firmware enabled regulator */ unsigned apply_uV:1; /* apply uV constraint if min == max */ unsigned ramp_disable:1; /* disable ramp delay */ + unsigned pull_down:1; /* pull down resistor when regulator off */ }; /** From 57f66b78860968fc7eddc9ce25f8e57f7e5000bd Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 11 Jun 2015 17:37:05 -0700 Subject: [PATCH 7/8] regulator: Add soft start support Some regulators support a "soft start" feature where the voltage ramps up slowly when the regulator is enabled. Add an op (set_soft_start) and a DT property + constraint to support this. Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.txt | 1 + drivers/regulator/core.c | 8 ++++++++ drivers/regulator/of_regulator.c | 3 +++ include/linux/regulator/driver.h | 2 ++ include/linux/regulator/machine.h | 1 + 5 files changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 6c79fd70ab5a..4b1df61ccbd7 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -19,6 +19,7 @@ Optional properties: design requires. This property describes the total system ramp time required due to the combination of internal ramping of the regulator itself, and board design issues such as trace capacitance and load on the supply. +- regulator-soft-start: Enable soft start so that voltage ramps slowly - regulator-state-mem sub-root node for Suspend-to-RAM mode : suspend to memory, the device goes to sleep, but all data stored in memory, only some external interrupt can wake the device. diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 60fcfba52592..6dfb2d6c19ae 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1059,6 +1059,14 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } + if (rdev->constraints->soft_start && ops->set_soft_start) { + ret = ops->set_soft_start(rdev); + if (ret < 0) { + rdev_err(rdev, "failed to set soft start\n"); + goto out; + } + } + print_constraints(rdev); return 0; out: diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index c3433db0acda..207da037cd2d 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -84,6 +84,9 @@ static void of_get_regulation_constraints(struct device_node *np, if (!ret) constraints->enable_time = pval; + constraints->soft_start = of_property_read_bool(np, + "regulator-soft-start"); + if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) { if (desc && desc->of_map_mode) { ret = desc->of_map_mode(pval); diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 76144a337ff7..e0635d0894aa 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -161,6 +161,8 @@ struct regulator_ops { unsigned int old_selector, unsigned int new_selector); + int (*set_soft_start) (struct regulator_dev *); + /* report regulator status ... most other accessors report * control inputs, this reports results of combining inputs * from Linux (and other sources) with the actual load. diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 8ffb0619a03c..7f7d0a3fe1e1 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -142,6 +142,7 @@ struct regulation_constraints { unsigned boot_on:1; /* bootloader/firmware enabled regulator */ unsigned apply_uV:1; /* apply uV constraint if min == max */ unsigned ramp_disable:1; /* disable ramp delay */ + unsigned soft_start:1; /* ramp voltage slowly */ unsigned pull_down:1; /* pull down resistor when regulator off */ }; From 36e4f839de59b6216a16cdf5c1d3263f4dbd9421 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 11 Jun 2015 17:37:06 -0700 Subject: [PATCH 8/8] regulator: Add input current limit support Some regulators can limit their input current (typically annotated as ilim). Add an op (set_input_current_limit) and a DT property + constraint to support this. Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/regulator.txt | 1 + drivers/regulator/core.c | 9 +++++++++ drivers/regulator/of_regulator.c | 4 ++++ include/linux/regulator/driver.h | 3 +++ include/linux/regulator/machine.h | 2 ++ 5 files changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 4b1df61ccbd7..e29db73e55f4 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -7,6 +7,7 @@ Optional properties: - regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops - regulator-min-microamp: smallest current consumers may set - regulator-max-microamp: largest current consumers may set +- regulator-input-current-limit-microamp: maximum input current regulator allows - regulator-always-on: boolean, regulator should never be disabled - regulator-boot-on: bootloader/firmware enabled regulator - regulator-allow-bypass: allow the regulator to go into bypass mode diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6dfb2d6c19ae..ba565416d1d0 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1008,6 +1008,15 @@ static int set_machine_constraints(struct regulator_dev *rdev, if (ret != 0) goto out; + if (rdev->constraints->ilim_uA && ops->set_input_current_limit) { + ret = ops->set_input_current_limit(rdev, + rdev->constraints->ilim_uA); + if (ret < 0) { + rdev_err(rdev, "failed to set input limit\n"); + goto out; + } + } + /* do we need to setup our suspend state */ if (rdev->constraints->initial_state) { ret = suspend_prepare(rdev, rdev->constraints->initial_state); diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 207da037cd2d..f025c1047d0a 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -58,6 +58,10 @@ static void of_get_regulation_constraints(struct device_node *np, if (!of_property_read_u32(np, "regulator-max-microamp", &pval)) constraints->max_uA = pval; + if (!of_property_read_u32(np, "regulator-input-current-limit-microamp", + &pval)) + constraints->ilim_uA = pval; + /* Current change possible? */ if (constraints->min_uA != constraints->max_uA) constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index e0635d0894aa..125264f8be93 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -91,6 +91,7 @@ struct regulator_linear_range { * @set_current_limit: Configure a limit for a current-limited regulator. * The driver should select the current closest to max_uA. * @get_current_limit: Get the configured limit for a current-limited regulator. + * @set_input_current_limit: Configure an input limit. * * @set_mode: Set the configured operating mode for the regulator. * @get_mode: Get the configured operating mode for the regulator. @@ -145,6 +146,8 @@ struct regulator_ops { int min_uA, int max_uA); int (*get_current_limit) (struct regulator_dev *); + int (*set_input_current_limit) (struct regulator_dev *, int lim_uA); + /* enable/disable regulator */ int (*enable) (struct regulator_dev *); int (*disable) (struct regulator_dev *); diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 7f7d0a3fe1e1..85a3b457de51 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -75,6 +75,7 @@ struct regulator_state { * * @min_uA: Smallest current consumers may set. * @max_uA: Largest current consumers may set. + * @ilim_uA: Maximum input current. * @system_load: Load that isn't captured by any consumer requests. * * @valid_modes_mask: Mask of modes which may be configured by consumers. @@ -113,6 +114,7 @@ struct regulation_constraints { /* current output range (inclusive) - for current control */ int min_uA; int max_uA; + int ilim_uA; int system_load;