lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4FB89E6D.7000206@nvidia.com>
Date:	Sun, 20 May 2012 13:04:05 +0530
From:	Laxman Dewangan <ldewangan@...dia.com>
To:	Mark Brown <broonie@...nsource.wolfsonmicro.com>
CC:	"lrg@...com" <lrg@...com>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
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, &regulator_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(&regulator_list_mutex);

-        rdev = regulator_dev_lookup(dev, id, &ret);
+        rdev = regulator_dev_lookup(dev, of_node, id, &ret);
         if (rdev)
                 goto found;

:::::::::::
}

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ