From: Tim Bird <tim.bird@sonymobile.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Bjorn Andersson <Bjorn.Andersson@sonymobile.com>
Subject: [PATCH] regulator: Support different config and dev of_nodes in regulator_register
Date: Wed, 4 Feb 2015 15:19:57 -0800 [thread overview]
Message-ID: <54D2A91D.5090700@sonymobile.com> (raw)
Support calling regulator_register with a dev node and a config node
with different of_nodes. This is useful when a single driver
wishes to register multiple child regulators.
Without this you get silent failures allocating a supply
for a regulator which is registered using the device node of the
regulator's DT parent (but it's own DT node).
Signed-off-by: Tim Bird <tim.bird@sonymobile.com>
---
I encountered a problem where I did a devm_regulator_register with
a dev (for a charger driver) and a config (for the regulator child
of the driver) that had different of_nodes. In this case, inside
regulator_dev_lookup the code did not find the supply that I had
specified in the child regulator's DT node. The DT setup looked
as follows:
charger@1000 {
compatible = "qcom,pm8941-charger";
reg = <0x1000 0x700>;
....
chg_otg {
regulator_name = "chg_otg";
otg-supply = <&pm8941_mvs1>;
...
}
}
This code checks the of_node of specified in the struct regulator_config
if the supply is not found in the dev.of_node. This code has no effect
if dev.of_node and config.of_node are the same, so it shouldn't affect
any existing (working) code.
drivers/regulator/core.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 128b432..36c5d78 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -128,13 +128,16 @@ static bool have_full_constraints(void)
/**
* of_get_regulator - get a regulator device node based on supply name
* @dev: Device pointer for the consumer (of regulator) device
+ * @config: pointer to config for regulator registration
* @supply: regulator supply name
*
* Extract the regulator device node corresponding to the supply name.
* returns the device node corresponding to the regulator if found, else
* returns NULL.
*/
-static struct device_node *of_get_regulator(struct device *dev, const char *supply)
+static struct device_node *of_get_regulator(struct device *dev,
+ const struct regulator_config *config,
+ const char *supply)
{
struct device_node *regnode = NULL;
char prop_name[32]; /* 32 is max size of property name */
@@ -147,7 +150,15 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
if (!regnode) {
dev_dbg(dev, "Looking up %s property in node %s failed",
prop_name, dev->of_node->full_name);
- return NULL;
+ if (!config || !config->of_node ||
+ config->of_node == dev->of_node)
+ return NULL;
+ regnode = of_parse_phandle(config->of_node, prop_name, 0);
+ if (!regnode) {
+ dev_dbg(dev, "Looking up %s property in node %s failed",
+ prop_name, dev->of_node->full_name);
+ return NULL;
+ }
}
return regnode;
}
@@ -1284,9 +1295,10 @@ static void regulator_supply_alias(struct device **dev, const char **supply)
}
}
-static struct regulator_dev *regulator_dev_lookup(struct device *dev,
- const char *supply,
- int *ret)
+static struct regulator_dev *regulator_dev_config_lookup(struct device *dev,
+ const struct regulator_config *config,
+ const char *supply,
+ int *ret)
{
struct regulator_dev *r;
struct device_node *node;
@@ -1297,7 +1309,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
/* first do a dt based lookup */
if (dev && dev->of_node) {
- node = of_get_regulator(dev, supply);
+ node = of_get_regulator(dev, config, supply);
if (node) {
list_for_each_entry(r, ®ulator_list, list)
if (r->dev.parent &&
@@ -1334,7 +1346,6 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
return map->regulator;
}
-
return NULL;
}
@@ -1362,7 +1373,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
mutex_lock(®ulator_list_mutex);
- rdev = regulator_dev_lookup(dev, id, &ret);
+ rdev = regulator_dev_config_lookup(dev, NULL, id, &ret);
if (rdev)
goto found;
@@ -3642,7 +3653,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (supply) {
struct regulator_dev *r;
- r = regulator_dev_lookup(dev, supply, &ret);
+ r = regulator_dev_config_lookup(dev, config, supply, &ret);
if (ret == -ENODEV) {
/*
--
1.8.2.2
next reply other threads:[~2015-02-04 23:20 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-04 23:19 Tim Bird [this message]
2015-02-05 1:59 ` [PATCH] regulator: Support different config and dev of_nodes in regulator_register Mark Brown
2015-02-05 17:33 ` Tim Bird
2015-02-05 17:43 ` Mark Brown
2015-02-05 18:37 ` Tim Bird
2015-02-05 19:27 ` Mark Brown
2015-02-05 22:08 ` Bjorn Andersson
2015-02-06 0:32 ` Mark Brown
2015-02-06 0:52 ` Bjorn Andersson
2015-02-06 11:49 ` Mark Brown
2015-02-06 19:56 ` Tim Bird
2015-02-11 17:21 ` Tim Bird
2015-02-12 2:32 ` Mark Brown
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=54D2A91D.5090700@sonymobile.com \
--to=tim.bird@sonymobile.com \
--cc=Bjorn.Andersson@sonymobile.com \
--cc=broonie@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.