[PATCH v2] of: reserved_mem: Introduce devres-managed initialization function

From: Mukesh Ojha

Date: Thu Jul 30 2026 - 03:45:39 EST


From: Konrad Dybcio <konrad.dybcio@xxxxxxxxxxxxxxxx>

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@xxxxxxxxxxxxxxxx>
Signed-off-by: Mukesh Ojha <mukesh.ojha@xxxxxxxxxxxxxxxx>
---
Changes since v1: https://lore.kernel.org/lkml/20260703193855.110619-2-mukesh.ojha@xxxxxxxxxxxxxxxx/
- Separated from big series with multiple API users to avoid clogging the
series. Instead of merging all at once, the plan is to land this API
first, then post the individual subsystem patches that use the API.
There is enough user of this API given in the last series.
- Rebased on latest Linux next tag.


drivers/of/of_reserved_mem.c | 44 +++++++++++++++++++++++++++++++++
include/linux/of_reserved_mem.h | 7 ++++++
2 files changed, 51 insertions(+)

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 7b1616b9c6c2..8c9d6395d6a3 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -796,6 +796,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;
--
2.53.0