/**
  * of_get_regulator - get a regulator device node based on supply name
- * @dev: Device pointer for the consumer (of regulator) device
+ * @dev: Device pointer for dev_printk() messages
+ * @node: Device node pointer for supply property lookup
  * @supply: regulator supply name
  *
  * Extract the regulator device node corresponding to the supply name.
  * Return: Pointer to the &struct device_node corresponding to the regulator
  *        if found, or %NULL if not found.
  */
-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 *node,
+                                           const char *supply)
 {
        struct device_node *regnode = NULL;
        char prop_name[64]; /* 64 is max size of property name */
 
-       dev_dbg(dev, "Looking up %s-supply from device tree\n", supply);
+       dev_dbg(dev, "Looking up %s-supply from device node %pOF\n", supply, node);
 
        snprintf(prop_name, 64, "%s-supply", supply);
-       regnode = of_parse_phandle(dev->of_node, prop_name, 0);
+       regnode = of_parse_phandle(node, prop_name, 0);
        if (regnode)
                return regnode;
 
 /**
  * of_regulator_dev_lookup - lookup a regulator device with device tree only
  * @dev: Device pointer for regulator supply lookup.
+ * @np: Device node pointer for regulator supply lookup.
  * @supply: Supply name or regulator ID.
  *
  * Return: Pointer to the &struct regulator_dev on success, or ERR_PTR()
  * * -%ENODEV if lookup fails permanently.
  * * -%EPROBE_DEFER if lookup could succeed in the future.
  */
-struct regulator_dev *of_regulator_dev_lookup(struct device *dev,
+struct regulator_dev *of_regulator_dev_lookup(struct device *dev, struct device_node *np,
                                              const char *supply)
 {
        struct regulator_dev *r;
        struct device_node *node;
 
-       node = of_get_regulator(dev, supply);
+       node = of_get_regulator(dev, np, supply);
        if (node) {
                r = of_find_regulator_by_node(node);
                of_node_put(node);
        return ERR_PTR(-ENODEV);
 }
 
+static struct regulator *_of_regulator_get(struct device *dev, struct device_node *node,
+                                          const char *id, enum regulator_get_type get_type)
+{
+       struct regulator_dev *r;
+       int ret;
+
+       ret = _regulator_get_common_check(dev, id, get_type);
+       if (ret)
+               return ERR_PTR(ret);
+
+       r = of_regulator_dev_lookup(dev, node, id);
+       return _regulator_get_common(r, dev, id, get_type);
+}
+
+/**
+ * of_regulator_get_optional - get optional regulator via device tree lookup
+ * @dev: device used for dev_printk() messages
+ * @node: device node for regulator "consumer"
+ * @id: Supply name
+ *
+ * Return: pointer to struct regulator corresponding to the regulator producer,
+ *        or PTR_ERR() encoded error number.
+ *
+ * This is intended for use by consumers that want to get a regulator
+ * supply directly from a device node, and can and want to deal with
+ * absence of such supplies. This will _not_ consider supply aliases.
+ * See regulator_dev_lookup().
+ */
+struct regulator *of_regulator_get_optional(struct device *dev,
+                                           struct device_node *node,
+                                           const char *id)
+{
+       return _of_regulator_get(dev, node, id, OPTIONAL_GET);
+}
+EXPORT_SYMBOL_GPL(of_regulator_get_optional);
+
 /*
  * Returns number of regulators coupled with rdev.
  */
 
 void regulator_put(struct regulator *regulator);
 void devm_regulator_put(struct regulator *regulator);
 
+#if IS_ENABLED(CONFIG_OF)
+struct regulator *__must_check of_regulator_get_optional(struct device *dev,
+                                                        struct device_node *node,
+                                                        const char *id);
+#else
+static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev,
+                                                                      struct device_node *node,
+                                                                      const char *id)
+{
+       return ERR_PTR(-ENODEV);
+}
+#endif
+
 int regulator_register_supply_alias(struct device *dev, const char *id,
                                    struct device *alias_dev,
                                    const char *alias_id);
        return ERR_PTR(-ENODEV);
 }
 
+static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev,
+                                                                      struct device_node *node,
+                                                                      const char *id)
+{
+       return ERR_PTR(-ENODEV);
+}
+
 static inline void regulator_put(struct regulator *regulator)
 {
 }