[PATCH RFC 1/4] regulator: add devm_fwnode family of functions
From: Griffin Kroah-Hartman
Date: Fri May 08 2026 - 08:57:27 EST
Add devm_fwnode_regulator_get and variants.
These function wrappers allow regulators to be accessed from the fwnode
struct without any casts.
Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@xxxxxxxxxxxxx>
---
drivers/regulator/devres.c | 66 ++++++++++++++++++++++++++++++++++++++
include/linux/regulator/consumer.h | 30 +++++++++++++++++
2 files changed, 96 insertions(+)
diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
index 615deba5d22c8ce190c69081c94651d8df93d002..f525b1f48bcf18593798f6fa520ccdfc656f6b6c 100644
--- a/drivers/regulator/devres.c
+++ b/drivers/regulator/devres.c
@@ -11,6 +11,7 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/module.h>
+#include <linux/of.h>
#include "internal.h"
@@ -803,4 +804,69 @@ struct regulator *devm_of_regulator_get_optional(struct device *dev, struct devi
return _devm_of_regulator_get(dev, node, id, OPTIONAL_GET);
}
EXPORT_SYMBOL_GPL(devm_of_regulator_get_optional);
+
+static struct regulator *_devm_fwnode_regulator_get(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id,
+ enum regulator_get_type get_type)
+{
+ if (is_of_node(fwnode))
+ return _devm_of_regulator_get(dev, to_of_node(fwnode), id, get_type);
+
+ return ERR_PTR(-ENODEV);
+}
+
+/**
+ * devm_fwnode_regulator_get() - get resource managed regulator from firmware node
+ * @dev: device to supply
+ * @fwnode: firmware node to get regulator from
+ * @id: supply name or regulator ID.
+ *
+ * Managed of_regulator_get(). Regulators returned from this
+ * function are automatically regulator_put() on driver detach. See
+ * of_regulator_get() for more information.
+ */
+struct regulator *devm_fwnode_regulator_get(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return _devm_fwnode_regulator_get(dev, fwnode, id, NORMAL_GET);
+}
+EXPORT_SYMBOL_GPL(devm_fwnode_regulator_get);
+
+/**
+ * devm_fwnode_regulator_get_exclusive() - get resource managed regulator from firmware node
+ * @dev: device to supply
+ * @fwnode: firmware node to get regulator from
+ * @id: supply name or regulator ID.
+ *
+ * Managed of_regulator_get_exclusive(). Regulators returned from this
+ * function are automatically regulator_put() on driver detach. See
+ * of_regulator_get_exclusive() for more information.
+ */
+struct regulator *devm_fwnode_regulator_get_exclusive(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return _devm_fwnode_regulator_get(dev, fwnode, id, EXCLUSIVE_GET);
+}
+EXPORT_SYMBOL_GPL(devm_fwnode_regulator_get_exclusive);
+
+/**
+ * devm_fwnode_regulator_get_optional() - get resource managed regulator from firmware node
+ * @dev: device to supply
+ * @fwnode: firmware node to get regulator from
+ * @id: supply name or regulator ID.
+ *
+ * Managed of_regulator_get_optional(). Regulators returned from this
+ * function are automatically regulator_put() on driver detach. See
+ * of_regulator_get_optional() for more information.
+ */
+struct regulator *devm_fwnode_regulator_get_optional(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return _devm_fwnode_regulator_get(dev, fwnode, id, OPTIONAL_GET);
+}
+EXPORT_SYMBOL_GPL(devm_fwnode_regulator_get_optional);
#endif
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 56fe2693d9b2284d04ebae50165f9aa7b1b3fee4..7c3aedf7f4902c4e3e8e2f5ecf6e4323b77658f3 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -691,6 +691,15 @@ struct regulator *__must_check devm_of_regulator_get_optional(struct device *dev
const char *id);
int __must_check of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
struct regulator_bulk_data **consumers);
+struct regulator *__must_check devm_fwnode_regulator_get(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id);
+struct regulator *__must_check devm_fwnode_regulator_get_exclusive(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id);
+struct regulator *__must_check devm_fwnode_regulator_get_optional(struct device *dev,
+ struct fwnode_handle *fwnode,
+ const char *id);
#else
static inline struct regulator *__must_check of_regulator_get_optional(struct device *dev,
struct device_node *node,
@@ -712,6 +721,27 @@ static inline int of_regulator_bulk_get_all(struct device *dev, struct device_no
return 0;
}
+static inline struct regulator *__must_check
+devm_fwnode_regulator_get(struct device *dev, struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return NULL;
+}
+
+static inline struct regulator *__must_check
+devm_fwnode_regulator_get_exclusive(struct device *dev, struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return NULL;
+}
+
+static inline struct regulator *__must_check
+devm_fwnode_regulator_get_optional(struct device *dev, struct fwnode_handle *fwnode,
+ const char *id)
+{
+ return NULL;
+}
+
#endif
static inline int regulator_set_voltage_triplet(struct regulator *regulator,
--
2.43.0