From: Sascha Hauer <s.hauer@pengutronix.de>
To: linux-kernel@vger.kernel.org
Cc: Liam Girdwood <lgirdwood@gmail.com>,
Mark Brown <broonie@kernel.org>,
kernel@pengutronix.de, alkml@pengutronix.de,
Sascha Hauer <s.hauer@pengutronix.de>
Subject: [PATCH 6/8] regulator: core: Propagate voltage changes to supply regulators
Date: Tue, 13 Oct 2015 12:45:29 +0200 [thread overview]
Message-ID: <1444733131-26995-7-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1444733131-26995-1-git-send-email-s.hauer@pengutronix.de>
Until now changing the voltage of a regulator only ever effected the
regulator itself, but never its supplies. It's a common pattern though
to put LDO regulators behind switching regulators. The switching
regulators efficiently drop the input voltage but have a high ripple on
their output. The output is then cleaned up by the LDOs. For higher
energy efficiency the voltage drop at the LDOs should be minimized. For
this scenario we need to propagate the voltage change to the supply
regulators. Another scenario where voltage propagation is desired is
a regulator which only consists of a switch and thus cannot regulate
voltages itself. In this case we can pass setting voltages to the
supply.
This patch adds support for voltage propagation. We do voltage
propagation when the current regulator has a minimum dropout voltage
specified or if the current regulator lacks a get_voltage operation
(indicating it's a switch and not a regulator).
Changing the supply voltage must be done carefully. When we are
increasing the current regulators output we must first increase the
supply voltage and then the regulator itself. When we are decreasing the
current regulators voltage we must decrease the supply voltage after
changing the current regulators voltage.
Calculating the optimum voltage for the supply regulator is a bit tricky
since the simple approach of just adding the desired minimum voltage and
the minimum dropout is not enough. It may happen that the current
regulator does not support the desired minimum voltage, but only a
higher one. This means we have to figure out the lowest voltage
supported by the regulator that is higher than the minimum desired
voltage. For this regulator_get_voltage_floor is used.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/regulator/core.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 6623538..a01f833 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2810,6 +2810,8 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
int ret = 0;
int old_min_uV, old_max_uV;
int current_uV;
+ int best_supply_uV = 0;
+ int supply_change_uV = 0;
/* If we're setting the same range as last time the change
* should be a noop (some cpufreq implementations use the same
@@ -2853,10 +2855,51 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
if (ret < 0)
goto out2;
+ if (rdev->supply && (rdev->desc->min_dropout_uv ||
+ !rdev->desc->ops->get_voltage)) {
+ int current_supply_uV;
+
+ best_supply_uV = regulator_get_voltage_floor(regulator, min_uV);
+ if (best_supply_uV < 0) {
+ ret = best_supply_uV;
+ goto out2;
+ }
+
+ best_supply_uV += rdev->desc->min_dropout_uv;
+
+ current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);
+ if (current_supply_uV < 0) {
+ ret = current_supply_uV;
+ goto out2;
+ }
+
+ supply_change_uV = best_supply_uV - current_supply_uV;
+ }
+
+ if (supply_change_uV > 0) {
+ ret = regulator_set_voltage_unlocked(rdev->supply,
+ best_supply_uV, INT_MAX);
+ if (ret) {
+ dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n",
+ ret);
+ goto out2;
+ }
+ }
+
ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
if (ret < 0)
goto out2;
+ if (supply_change_uV < 0) {
+ ret = regulator_set_voltage_unlocked(rdev->supply,
+ best_supply_uV, INT_MAX);
+ if (ret)
+ dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n",
+ ret);
+ /* No need to fail here */
+ ret = 0;
+ }
+
out:
return ret;
out2:
@@ -2888,11 +2931,11 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
{
int ret = 0;
- mutex_lock(®ulator->rdev->mutex);
+ regulator_lock_supply(regulator->rdev);
ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV);
- mutex_unlock(®ulator->rdev->mutex);
+ regulator_unlock_supply(regulator->rdev);
return ret;
}
--
2.6.1
next prev parent reply other threads:[~2015-10-13 10:45 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-13 10:45 [PATCH v2] regulator: " Sascha Hauer
2015-10-13 10:45 ` [PATCH 1/8] regulator: core: create unlocked version of regulator_list_voltage Sascha Hauer
2015-10-16 15:26 ` Mark Brown
2015-10-13 10:45 ` [PATCH 2/8] regulator: core: create unlocked version of regulator_set_voltage Sascha Hauer
2015-10-16 17:04 ` Applied "regulator: core: create unlocked version of regulator_set_voltage" to the regulator tree Mark Brown
2015-10-13 10:45 ` [PATCH 3/8] regulator: introduce min_dropout_uv Sascha Hauer
2015-10-16 16:11 ` Mark Brown
2015-10-16 16:41 ` Applied "regulator: introduce min_dropout_uv" to the regulator tree Mark Brown
2015-10-16 16:57 ` Mark Brown
2015-10-13 10:45 ` [PATCH 4/8] regulator: core: introduce function to lock regulators and its supplies Sascha Hauer
2015-10-13 10:45 ` [PATCH 5/8] regulator: introduce regulator_get_voltage_floor Sascha Hauer
2015-10-16 16:50 ` Mark Brown
2015-10-20 12:26 ` Sascha Hauer
2015-10-13 10:45 ` Sascha Hauer [this message]
2015-10-16 16:55 ` [PATCH 6/8] regulator: core: Propagate voltage changes to supply regulators Mark Brown
2015-10-13 10:45 ` [PATCH 7/8] regulator: i.MX anatop: Allow supply regulator Sascha Hauer
2015-10-13 10:45 ` [PATCH 8/8] ARM: i.MX6 Phytec PFLA02: Add supplies for the SoC internal regulators Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1444733131-26995-7-git-send-email-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=alkml@pengutronix.de \
--cc=broonie@kernel.org \
--cc=kernel@pengutronix.de \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®