[RFC PATCH 11/15] dm: core: Add static adjunct declarations for drivers
Simon Glass
sjg at chromium.org
Thu Mar 19 22:35:41 CET 2026
Add struct driver_adjunct and a .adjuncts field to struct driver,
allowing drivers to declare adjunct uclass memberships at compile time.
The core registers these automatically during probe via
device_bind_static_adjs(), before the driver's probe() runs.
This removes the need for custom probe functions that only call
device_add_uclass_adj(). The dynamic API remains available for cases
where adjuncts are conditional.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/core/adjunct.c | 17 +++++++++++++++++
drivers/core/device.c | 4 ++++
include/dm/device-internal.h | 16 ++++++++++++++++
include/dm/device.h | 21 +++++++++++++++++++++
4 files changed, 58 insertions(+)
diff --git a/drivers/core/adjunct.c b/drivers/core/adjunct.c
index 802d2761e6b..0e247bd4cb9 100644
--- a/drivers/core/adjunct.c
+++ b/drivers/core/adjunct.c
@@ -150,6 +150,23 @@ void *device_get_uclass_plat(struct udevice *dev, enum uclass_id id)
return device_get_adj_uclass_plat(dev, id);
}
+int device_bind_static_adjs(struct udevice *dev)
+{
+ const struct driver_adjunct *adj = dev->driver->adjuncts;
+ int ret;
+
+ if (!adj)
+ return 0;
+
+ for (; adj->id; adj++) {
+ ret = device_bind_adj_(dev, adj->id, adj->ops);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
int device_probe_adjs_(struct udevice *dev)
{
struct uclass_driver *uc_drv;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 2b7b3528e4c..fb35488e70c 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -168,6 +168,10 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
if (ret)
goto fail_uclass_bind;
+ ret = device_bind_static_adjs(dev);
+ if (ret)
+ goto fail_uclass_bind;
+
/* if we fail to bind we remove device from successors and free it */
if (drv->bind) {
ret = drv->bind(dev);
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index a129ddecf87..fdba288d55c 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -519,6 +519,17 @@ void *device_get_adj_uclass_priv(struct udevice *dev, enum uclass_id id);
*/
void *device_get_adj_uclass_plat(struct udevice *dev, enum uclass_id id);
+/**
+ * device_bind_static_adjs() - Register statically declared adjuncts
+ *
+ * Called during bind to register any adjuncts declared in the driver's
+ * adjuncts array.
+ *
+ * @dev: Device to register static adjuncts for
+ * Return: 0 if OK, -ve on error
+ */
+int device_bind_static_adjs(struct udevice *dev);
+
/**
* device_probe_adjs_() - Allocate private data for adjunct uclasses
*
@@ -581,6 +592,11 @@ static inline void *device_get_adj_uclass_plat(struct udevice *dev,
return NULL;
}
+static inline int device_bind_static_adjs(struct udevice *dev)
+{
+ return 0;
+}
+
static inline int device_probe_adjs_(struct udevice *dev)
{
return 0;
diff --git a/include/dm/device.h b/include/dm/device.h
index d93690d7a8b..4832a1ff634 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -354,6 +354,20 @@ struct udevice_id {
#define of_match_ptr(_ptr) NULL
#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
+/**
+ * struct driver_adjunct - Static adjunct declaration for a driver
+ *
+ * Allows a driver to declare membership in additional uclasses at compile
+ * time, rather than calling device_add_uclass_adj() dynamically.
+ *
+ * @id: Uclass ID for this adjunct membership
+ * @ops: Operations provided by this driver for the adjunct uclass
+ */
+struct driver_adjunct {
+ enum uclass_id id;
+ const void *ops;
+};
+
/**
* struct driver - A driver for a feature or peripheral
*
@@ -399,6 +413,10 @@ struct udevice_id {
* pointers defined by the driver, to implement driver functions required by
* the uclass.
* @flags: driver flags - see `DM_FLAG_...`
+ * @adjuncts: Sentinel-terminated array of static adjunct declarations, or
+ * NULL if the driver does not statically declare any adjuncts. Each entry
+ * specifies a uclass ID and ops pointer. The core registers these during
+ * probe, before calling the driver's probe function.
* @acpi_ops: Advanced Configuration and Power Interface (ACPI) operations,
* allowing the device to add things to the ACPI tables passed to Linux
*/
@@ -420,6 +438,9 @@ struct driver {
int per_child_plat_auto;
const void *ops; /* driver-specific operations */
uint32_t flags;
+#if CONFIG_IS_ENABLED(DM_UC_ADJUNCT)
+ const struct driver_adjunct *adjuncts;
+#endif
#if CONFIG_IS_ENABLED(ACPIGEN)
struct acpi_ops *acpi_ops;
#endif
--
2.43.0
More information about the U-Boot
mailing list