From: Laxman Dewangan <ldewangan@nvidia.com>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: "lrg@ti.com" <lrg@ti.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] regulator: core: use correct device for device supply lookup
Date: Sun, 20 May 2012 13:04:05 +0530 [thread overview]
Message-ID: <4FB89E6D.7000206@nvidia.com> (raw)
In-Reply-To: <20120519231347.GD16590@opensource.wolfsonmicro.com>
On Sunday 20 May 2012 04:43 AM, Mark Brown wrote:
> * PGP Signed by an unknown key
>
> On Sun, May 20, 2012 at 02:43:18AM +0530, Laxman Dewangan wrote:
>
>> For mapping, the node should start from "regulators", not from pmu
>> on this example.
> What makes you say this? I'm really not even sure what it means.
> How does a node "start" from something? Supply mappings are direct
> links between consumers and regulators.
>
Sorry for long mail:
This is the issue in the tps65910-regulator.c where config.of_node is
not being passed correctly.
The flow for my debugging the issue is as follows:
The dts file looks like:
tps65911: tps65911@2d {
reg = <0x2d>
#gpio_cells = <2>
gpio_controller;
:::::::::
regulator {
ldo1_reg: ldo1 {
::::::::
/** regulator entry */
::::::::::::
::::::::::::
/* There is NO input supply on this node */
};
ldo2_reg: ldo2 {
::::::::
/** regulator entry */
::::::::::::
/* There is NO input supply on this node */
};
};
};
Now in the driver, when we register ldo1, the config.of_node should
contain the node of "ldo1_reg" and when we register ldo2 then
config.of_node should contain the node of "ldo2_reg".
In the tps65910-regulator.c, the parent device node is containing node
of "tps65911" i.e. pdev->dev.parent->of_node.
The same is also accessed by tps65910->dev->of_node as tps65910->dev is
pdev->dev.parent.
By executing the following code in tps65910-regulator.c, ptobe(),
config.of_node =
of_find_node_by_name(tps65910->dev->of_node,
info->name);
is always returning NULL.
This is because the info->name which are "ldo1" or "ldo2" are looked on
the parent node i.e. pdev->dev.parent->of_node, not inside child node
"regulator" of pdev->dev.parent->of_node. The function
of_find_node_by_name() only looked for props on that node ("tps65911"),
does not search from child node "regulator".
So for fixing this,
The search for info->name should start from the child node "regulator"
of the "tps65911" to get proper regulator of_node for for regulator
being register.
So I first searched for child node "regulator" from parent node
"tps65911" and then search for info->name ("ldo1" or "ldo2") from this
child node "regulator":
struct device_node *np = pdev->dev.parent->of_node;
struct device_node *regulators;
regulators = of_find_node_by_name(np, "regulators");
if (regulators)
config.of_node = of_find_node_by_name(regulators, info->name);
After fixing this piece of code, regulator_get() from any driver get
success.
This particular change should be in tps65910-regulator.c file. I fixed
this in my yesterday's patch 2/5 but lack of explanation on the change
log, it was unclear.
From consumer perspecive:
when ldo1_reg get registerd, the config.of_node should contain the node
handle for ldo1_reg and so it will get stored in rdev->dev.of_node as
ldo1_reg.
Similarly for ldo2_reg, config.of_node should contain node for ldo2_reg
and so will get stored in the rdev->dev.of_node as ldo2_reg;
ldo1 and ldo2 are get added in the regulator_list after successfully
registration for regualtors.
The consumer defines the supply on the dts file as
xyz_dev: xyz {
:::::::::::::::
vmmc-supply = <&ldo1_reg>;
::::::::::::
}
consumer driver calls the regulator_get as
regulator_get(dev, "vmmc");
Here dev->of_node contains the node for device" xyz_dev".
The "vmmc-supply" is being searched in xyz_dev and so it founds the
regulator node as ldo1_reg.
This node get compared from all regulaors's of_node available in
regulator_list as:
node = of_get_regulator(dev, supply);
if (node) {
list_for_each_entry(r, ®ulator_list, list)
if (r->dev.parent &&
node == r->dev.of_node)
return r;
}
So to get this search success, the r->dev.of_node should contain the
regulator specific nodes i.e. ldo1_reg or ldo2_reg.
So after fixing the above code,it worked fine.
> | context of the class device we create. I can't think of any situation
> | where I'd expect that to make matters any better - the class device
> | should certainly never appear in the device tree and isn't going to have
> | a stable name for non-DT systems either.
>
> *Please* engage with this, especially the non-DT part. You need to
> explain how what you're saying is related to the patch you posted, you
> keep talking about a "proper" config.of_node and saying this happens to
> make your system work but this isn't visibily related to the patch you
> posted.
>
> What is not "proper" about the of_node that was supplied for the
> regulator being registered? In what way is this related to the device
> used by the regulator functioning as a consumer to request a supply?
This is the issue arise when regulator being registered have the input
supply.
I am assuming the above fix is there in tps65910-regulator.c.
The dts file looks as
tps65911: tps65911@2d {
reg = <0x2d>
#gpio_cells = <2>
gpio_controller;
:::::::::
regulator {
ldo1_reg: ldo1 {
::::::::
/** regulatr entry */
::::::::::::
::::::::::::
/* There is NO input supply on this node */
};
ldo2_reg: ldo2 {
::::::::
/** regulatr entry */
::::::::::::
ldo2-supply = <&ldo1_reg>; /* So ldo1 supply the ldo2. */
};
};
};
ldo1 registration went fine.
During ldo2 registration, I passed the regulator_desc->supply_name as ldo2.
Here we are passing the config.dev = pdev->dev.parent.
And hence the config.dev.of_node is containing the node of "tps6511".
As I have fixed in tps65911-regulator.c, config.of_node contains the
node i.e. "ldo1_reg" or "ldo2_reg" for regulator being registered.
In regulator_register(), following piece of code actually fails in the
case config.of_node is not same as the dev->of_node and in my case it is
not same. For fixed regulator case it is same and hence it is passing.
if (supply) {
struct regulator_dev *r;
r = regulator_dev_lookup(dev, supply, &ret);
Here dev->of_node is containing the node of "tps65911" and so search of
property "ldo1-supply" failed.
Does following change in core.c make sense to handle the case where
config->of_node and dev->of_node is not same? Here we still use the dev
which is passed by config->dev and make use of config->of_node.
- r = regulator_dev_lookup(dev, supply, &ret);
+ r = regulator_dev_lookup(dev, config->of_node, supply,
&ret);
and regulator_dev_lookup() should look for of_node which is passed
rather than the dev->of_node.
static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+ struct device_node *of_node,
const char *supply,
int *ret)
{
struct regulator_dev *r;
struct device_node *node;
/* first do a dt based lookup */
- if (dev && dev->of_node) {
- node = of_get_regulator(dev, supply);
+ if (dev && of_node) {
+ node = of_get_regulator(dev, of_node, supply);
:::::::::::
}
- static struct device_node *of_get_regulator(struct device *dev, const
char *supply)
+ static struct device_node *of_get_regulator(struct device *dev, struct
device_node *of_node, const char *supply)
{
struct device_node *regnode = NULL;
char prop_name[32]; /* 32 is max size of property name */
snprintf(prop_name, 32, "%s-supply", supply);
- regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+ regnode = of_parse_phandle(of_node, prop_name, 0);
:::::::::
}
static struct regulator *_regulator_get(struct device *dev, const char *id,
int exclusive)
{
struct regulator_dev *rdev;
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
const char *devname = NULL;
+ struct device_node *of_node = NULL;
int ret;
if (id == NULL) {
pr_err("get() with no identifier\n");
return regulator;
}
if (dev) {
devname = dev_name(dev);
+ of_node = dev->of_node;
}
mutex_lock(®ulator_list_mutex);
- rdev = regulator_dev_lookup(dev, id, &ret);
+ rdev = regulator_dev_lookup(dev, of_node, id, &ret);
if (rdev)
goto found;
:::::::::::
}
next prev parent reply other threads:[~2012-05-20 7:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-19 14:14 [PATCH] regulator: core: use correct device for device supply lookup Laxman Dewangan
2012-05-19 16:41 ` Mark Brown
2012-05-19 17:14 ` Laxman Dewangan
2012-05-19 17:20 ` Laxman Dewangan
2012-05-19 17:40 ` Mark Brown
2012-05-19 17:56 ` Laxman Dewangan
2012-05-19 18:26 ` Mark Brown
2012-05-19 19:03 ` Laxman Dewangan
2012-05-19 20:50 ` Mark Brown
2012-05-19 21:13 ` Laxman Dewangan
2012-05-19 23:13 ` Mark Brown
2012-05-20 7:34 ` Laxman Dewangan [this message]
2012-05-20 9:01 ` Mark Brown
[not found] ` <4FB8C9EF.7010400@nvidia.com>
2012-05-20 12:06 ` Mark Brown
2012-05-20 12:14 ` Laxman Dewangan
2012-05-20 12:10 ` Laxman Dewangan
2012-05-19 17:28 ` 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=4FB89E6D.7000206@nvidia.com \
--to=ldewangan@nvidia.com \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lrg@ti.com \
/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.