#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>
        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)
        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, ®ulator_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, ®ulator_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)
 
        mutex_lock(®ulator_list_mutex);
 
+       rdev = regulator_dev_lookup(dev, id);
+       if (rdev)
+               goto found;
+
        list_for_each_entry(map, ®ulator_map_list, list) {
                /* If the mapping has a device set up it must match */
                if (map->dev_name &&
        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);
        if (ret < 0)
                goto scrub;
 
-       if (init_data->supply_regulator) {
+       if (init_data->supply_regulator)
+               supply = init_data->supply_regulator;
+       else if (regulator_desc->supply_name)
+               supply = regulator_desc->supply_name;
+
+       if (supply) {
                struct regulator_dev *r;
-               int found = 0;
 
-               list_for_each_entry(r, ®ulator_list, list) {
-                       if (strcmp(rdev_get_name(r),
-                                  init_data->supply_regulator) == 0) {
-                               found = 1;
-                               break;
-                       }
-               }
+               r = regulator_dev_lookup(dev, supply);
 
-               if (!found) {
-                       dev_err(dev, "Failed to find supply %s\n",
-                               init_data->supply_regulator);
+               if (!r) {
+                       dev_err(dev, "Failed to find supply %s\n", supply);
                        ret = -ENODEV;
                        goto scrub;
                }