From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH 13/19] driver: add devm_add_action()
Date: Wed, 28 Oct 2026 10:14:47 +0100 [thread overview]
Message-ID: <20261028092442.3300753-14-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20261028092442.3300753-1-a.fatoum@pengutronix.de>
From: Ahmad Fatoum <a.fatoum@barebox.org>
Add devm_add_action() and devm_add_action_or_reset() on top of
talloc_add_destructor() for drivers that need to undo things on remove.
As barebox calls the remove callbacks on shutdown, let's run the actions
there as well, but keep the managed memory, which may still be
referenced afterwards.
Assisted-by: Claude:fable-5.1
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
drivers/base/devres.c | 23 +++++++++++++++++++++++
drivers/base/driver.c | 1 +
include/driver.h | 1 +
include/linux/device.h | 38 ++++++++++++++++++++++++++++++++++++++
4 files changed, 63 insertions(+)
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 26abc47cd997..bf118ae0820d 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -36,6 +36,18 @@ void devres_release_all(struct device *dev)
dev->devres = NULL;
}
+/**
+ * devres_run_actions() - run the managed actions of a device
+ * @dev: device that is shut down
+ *
+ * Like devres_release_all(), but keeps the managed memory, which may
+ * still be referenced after shutdown.
+ */
+void devres_run_actions(struct device *dev)
+{
+ talloc_run_destructors(dev->devres);
+}
+
/*
* Memory must be DMA-safe like kmalloc()'s, so align it within the chunk
* and store the chunk pointer in front of it for devm_kfree().
@@ -145,3 +157,14 @@ char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...)
return p;
}
EXPORT_SYMBOL(devm_kasprintf);
+
+int devm_add_action(struct device *dev, void (*action)(void *), void *data)
+{
+ void *ctx = devres_ctx(dev);
+
+ if (!ctx)
+ return -ENOMEM;
+
+ return talloc_add_destructor(ctx, action, data);
+}
+EXPORT_SYMBOL(devm_add_action);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index e214408e12a3..f87ecb200feb 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -720,6 +720,7 @@ static void devices_shutdown(void)
pr_report_probe("%*sremove-> %s\n", 1 * 4, "", dev_name(dev));
remove(dev);
}
+ devres_run_actions(dev);
dev->driver = NULL;
}
}
diff --git a/include/driver.h b/include/driver.h
index 372b1297c6c4..c394c455b971 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -112,6 +112,7 @@ void free_device_res(struct device *dev);
void free_device(struct device *dev);
void devres_release_all(struct device *dev);
+void devres_run_actions(struct device *dev);
static inline void device_rescan(struct device *dev)
{
diff --git a/include/linux/device.h b/include/linux/device.h
index 595abf412180..9b14bc74fef6 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -101,6 +101,44 @@ static inline unsigned long *devm_bitmap_zalloc(struct device *dev,
gfp);
}
+/**
+ * devm_add_action() - add a custom action to the managed resources
+ * @dev: device that owns the action
+ * @action: function to call when the device is unbound, unregistered
+ * or shut down
+ * @data: argument to pass to @action
+ *
+ * Actions run in reverse order of registration, interleaved with the
+ * freeing of managed memory.
+ *
+ * Return: 0 on success, -ENOMEM if the action could not be registered.
+ */
+int devm_add_action(struct device *dev, void (*action)(void *), void *data);
+
+/**
+ * devm_add_action_or_reset() - add a custom action, running it on failure
+ * @dev: device that owns the action
+ * @action: function to call when the device is unbound, unregistered
+ * or shut down
+ * @data: argument to pass to @action
+ *
+ * Like devm_add_action(), but @action is called right away if it could
+ * not be registered.
+ *
+ * Return: 0 on success, -ENOMEM if the action could not be registered.
+ */
+static inline int devm_add_action_or_reset(struct device *dev,
+ void (*action)(void *), void *data)
+{
+ int ret;
+
+ ret = devm_add_action(dev, action, data);
+ if (ret)
+ action(data);
+
+ return ret;
+}
+
#define device_register register_device
#define device_unregister unregister_device
--
2.47.3
next prev parent reply other threads:[~2026-10-28 9:29 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 9:14 [PATCH 00/19] driver: add devm_ support Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 01/19] commands: devunbind: refuse to unbind devices that were never bound Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 02/19] commands: devunbind: don't poison the active list entry Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 03/19] talloc: remove unused talloc_steal() and talloc_steal_children() Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 04/19] talloc: free children in a loop Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 05/19] talloc: add support for destructors Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 06/19] test: self: talloc: add destructor tests Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 07/19] talloc: add talloc_run_destructors() Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 08/19] mfd: pca9450: don't free device-managed memory in probe error path Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 09/19] video: backlight-pwm: allocate brightness levels with devm_kcalloc Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 10/19] driver: implement devm_ allocation helpers on top of talloc Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 11/19] devres: Provide kmalloc_obj*-style API for devm_kmalloc Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 12/19] memory: atmel-ebi: use generic devm_kzalloc() Ahmad Fatoum
2026-10-28 9:14 ` Ahmad Fatoum [this message]
2026-10-28 9:14 ` [PATCH 14/19] test: self: add devm_ selftest Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 15/19] driver: add devm_request_mem_resource() Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 16/19] driver: make dev_platform_ioremap_resource() device-managed Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 17/19] treewide: rename dev_platform_ioremap_resource() to devm_platform_ioremap_resource() Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 18/19] driver: make dev_platform_get_and_ioremap_resource() device-managed Ahmad Fatoum
2026-10-28 9:14 ` [PATCH 19/19] serial: stm32: request the registers with devm_request_mem_resource() Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028092442.3300753-14-a.fatoum@pengutronix.de \
--to=a.fatoum@pengutronix.de \
--cc=a.fatoum@barebox.org \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox