Re: [PATCH v5 4/4] regulator: map consumer regulator based on device tree

2011-11-23 Thread Mark Brown
On Fri, Nov 18, 2011 at 04:47:20PM +0530, Rajendra Nayak wrote:

 + struct device_node *regnode = NULL;
 + char prop_name[32]; /* 32 is max size of property name */

There ought to be a #define for that though I can't see one right now -
this can't be the only place where we need to do stuff like this.

 +
 + dev_dbg(dev, Looking up %s-supply from device tree\n, supply);
 +
 + snprintf(prop_name, 32, %s-supply, supply);

sizeof().
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v5 4/4] regulator: map consumer regulator based on device tree

2011-11-18 Thread Rajendra Nayak
Device nodes in DT can associate themselves with one or more
regulators/supply by providing a list of phandles (to regulator nodes)
and corresponding supply names.

For Example:
devicenode: node@0x0 {
...
...
vmmc-supply = regulator1;
vpll-supply = regulator2;
};

The driver would then do a regulator_get(dev, vmmc); to get
regulator1 and do a regulator_get(dev, vpll); to get
regulator2.

of_get_regulator() extracts the regulator node for a given
device, based on the supply name.

Use it to look up the regulator for a given consumer from device tree, during
a regulator_get(). If not found fallback and lookup through
the regulator_map_list instead.

Also, since the regulator dt nodes can use the same binding to
associate with a parent regulator/supply, allow the drivers to
specify a supply_name, which can then be used to lookup dt
to find the parent phandle.

Signed-off-by: Rajendra Nayak rna...@ti.com
Acked-by: Grant Likely grant.lik...@secretlab.ca
Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com
---
 drivers/regulator/core.c |   79 --
 include/linux/regulator/driver.h |2 +
 2 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 8b01eb0..9867ebc 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -25,6 +25,8 @@
 #include linux/mutex.h
 #include linux/suspend.h
 #include linux/delay.h
+#include linux/of.h
+#include linux/regulator/of_regulator.h
 #include linux/regulator/consumer.h
 #include linux/regulator/driver.h
 #include linux/regulator/machine.h
@@ -132,6 +134,33 @@ static struct regulator *get_device_regulator(struct 
device *dev)
return NULL;
 }
 
+/**
+ * of_get_regulator - get a regulator device node based on supply name
+ * @dev: Device pointer for the consumer (of regulator) device
+ * @supply: regulator supply name
+ *
+ * Extract the regulator device node corresponding to the supply name.
+ * retruns 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)
+{
+   struct device_node *regnode = NULL;
+   char prop_name[32]; /* 32 is max size of property name */
+
+   dev_dbg(dev, Looking up %s-supply from device tree\n, supply);
+
+   snprintf(prop_name, 32, %s-supply, supply);
+   regnode = of_parse_phandle(dev-of_node, prop_name, 0);
+
+   if (!regnode) {
+   dev_warn(dev, %s property in node %s references invalid 
phandle,
+   prop_name, dev-of_node-full_name);
+   return NULL;
+   }
+   return regnode;
+}
+
 /* Platform voltage constraint check */
 static int regulator_check_voltage(struct regulator_dev *rdev,
   int *min_uV, int *max_uV)
@@ -1148,6 +1177,30 @@ static int _regulator_get_enable_time(struct 
regulator_dev *rdev)
return rdev-desc-ops-enable_time(rdev);
 }
 
+static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+const char *supply)
+{
+   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 (node)
+   list_for_each_entry(r, regulator_list, list)
+   if (r-dev.parent 
+   node == r-dev.of_node)
+   return r;
+   }
+
+   /* if not found, try doing it non-dt way */
+   list_for_each_entry(r, regulator_list, list)
+   if (strcmp(rdev_get_name(r), supply) == 0)
+   return r;
+
+   return NULL;
+}
+
 /* Internal regulator request function */
 static struct regulator *_regulator_get(struct device *dev, const char *id,
int exclusive)
@@ -1168,6 +1221,10 @@ static struct regulator *_regulator_get(struct device 
*dev, const char *id,
 
mutex_lock(regulator_list_mutex);
 
+   rdev = regulator_dev_lookup(dev, id);
+   if (rdev)
+   goto found;
+
list_for_each_entry(map, regulator_map_list, list) {
/* If the mapping has a device set up it must match */
if (map-dev_name 
@@ -2642,6 +2699,7 @@ struct regulator_dev *regulator_register(struct 
regulator_desc *regulator_desc,
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
int ret, i;
+   const char *supply = NULL;
 
if (regulator_desc == NULL)
return ERR_PTR(-EINVAL);
@@ -2718,21 +2776,18 @@ struct regulator_dev *regulator_register(struct 
regulator_desc *regulator_desc,
if (ret  0)