Messages in this thread | | | Date | Sun, 20 May 2012 13:04:05 +0530 | From | Laxman Dewangan <> | Subject | Re: [PATCH] regulator: core: use correct device for device supply lookup |
| |
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;
::::::::::: }
| |