summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Dybcio <konrad.dybcio@oss.qualcomm.com>2026-07-30 13:02:14 +0530
committerRob Herring (Arm) <robh@kernel.org>2026-08-11 16:54:37 -0500
commitb71ace1a003e57886ee65c21cab052d404c5b049 (patch)
tree6baa40def14a266f742f4566c7ca7024e19a807d
parentf423482666be05c5f74f2a75caee04aa493d524c (diff)
of: reserved_mem: Introduce devres-managed initialization function
Introduce devres-based helper for of_reserved_mem_device_init() to help fight dangling references and ever so slightly reduce the number of boilerplate deinitialization calls. Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Link: https://patch.msgid.link/20260730073214.1146432-1-mukesh.ojha@oss.qualcomm.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
-rw-r--r--drivers/of/of_reserved_mem.c44
-rw-r--r--include/linux/of_reserved_mem.h7
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 9ce55bfd7e2a..5f441a684567 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -788,6 +788,50 @@ void of_reserved_mem_device_release(struct device *dev)
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);
+static void devm_of_reserved_mem_device_release(struct device *dev, void *res)
+{
+ of_reserved_mem_device_release(*(struct device **)res);
+}
+
+static int devm_of_reserved_mem_device_init_by_idx(struct device *dev,
+ struct device_node *np, int idx)
+{
+ struct device **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_of_reserved_mem_device_release, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = of_reserved_mem_device_init_by_idx(dev, np, idx);
+ if (ret) {
+ devres_free(ptr);
+ return ret;
+ }
+
+ *ptr = dev;
+ devres_add(dev, ptr);
+
+ return 0;
+}
+
+/**
+ * devm_of_reserved_mem_device_init() - Resource managed of_reserved_mem_device_init()
+ * @dev: Pointer to the device to configure
+ *
+ * This is a resource managed version of of_reserved_mem_device_init().
+ * The reserved memory region will be released automatically when the device
+ * is unbound.
+ *
+ * Returns: Negative errno on failure or zero on success.
+ */
+int devm_of_reserved_mem_device_init(struct device *dev)
+{
+ return devm_of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
+}
+EXPORT_SYMBOL_GPL(devm_of_reserved_mem_device_init);
+
/**
* of_reserved_mem_lookup() - acquire reserved_mem from a device node
* @np: node pointer of the desired reserved-memory region
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index e8b20b29fa68..49da515859f2 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -40,6 +40,8 @@ int of_reserved_mem_device_init_by_name(struct device *dev,
const char *name);
void of_reserved_mem_device_release(struct device *dev);
+int devm_of_reserved_mem_device_init(struct device *dev);
+
struct reserved_mem *of_reserved_mem_lookup(struct device_node *np);
int of_reserved_mem_region_to_resource(const struct device_node *np,
unsigned int idx, struct resource *res);
@@ -68,6 +70,11 @@ static inline int of_reserved_mem_device_init_by_name(struct device *dev,
static inline void of_reserved_mem_device_release(struct device *pdev) { }
+static inline int devm_of_reserved_mem_device_init(struct device *dev)
+{
+ return -EOPNOTSUPP;
+}
+
static inline struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
{
return NULL;