[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