[RFC PATCH 00/15] RFC: dm: Add uclass adjunct support
Simon Glass
sjg at chromium.org
Thu Mar 19 22:35:30 CET 2026
[Note: this is marked RFC as I am still not sure that this is the best
approach. But this is my third redesign so I think it makes sense to get
some feedback before trying to refine it further]
U-Boot's driver model requires each device to belong to exactly one
uclass. Multi-function hardware must work around this by creating
child devices in different uclasses via device_bind_driver_to_node(),
with a NOP parent device.
This is quite common: at least 8 PMIC drivers bind sysreset children,
every Qualcomm GCC driver (15+ platforms) does this and several PHY
drivers bind clock children.
This series adds uclass adjuncts, which allow a device to register
in additional uclasses without creating child devices. Each adjunct
carries its own ops pointer, per-device uclass private/platform
data, and sequence number.
With this series, uclass lookup and iteration functions include
adjunct registrations alongside primary devices. The
uclass_foreach_dev() iterator walks all entries in the uclass,
including adjunct ones. Iterators that use a struct udevice * to
iterate (uclass_find_first_device() etc.) only see primary devices,
since they navigate via the embedded primary ucm.
A new ucm_ iterator API uses struct uclass_member * as the cursor,
enabling adjunct-aware iteration and lookup. It provides find, probe,
check, drvdata, seq and ofnode variants. uclass_foreach_dev_probe()
uses this internally so that it includes adjuncts.
As a concrete example, a Qualcomm GCC driver could register as
UCLASS_CLK (primary) with adjunct UCLASS_RESET and
UCLASS_POWER_DOMAIN, thus removing the UCLASS_NOP container and the
qcom_cc_bind() function. The raa215300 PMIC conversion in this series
demonstrates the pattern: one device, no child sysreset driver,
no dev_get_priv(dev->parent) indirection.
The mechanism is enabled by a new CONFIG_DM_UC_ADJUNCT option. Code size
is largely neutral without this, except for the change to add
dev_int_set_seq() which is used by PCI boards.
Note that a couple of linker-list fixes are included so that sandbox
will start up correctly. It still does not pass all tests though, due to
various bugs surfaced by this series. If we go ahead, we will need at
least one precursor series to resolve these pre-existing problems.
This is an RFC. The next steps could be:
- Convert one Qualcomm GCC driver to use adjuncts
- Convert one RK8xx PMIC from child-sysreset to adjunct
- Update per-subsystem ops accessors (clk_dev_ops(), etc.)
Simon Glass (15):
dm: Fix linker list alignment for ll_entry_get()
linker_lists: Fix end-marker alignment to prevent padding
dm: Add a way to write the internal seq_ member
dm: Rename uclass to uclass_ and add an accessor
dm: Add struct uclass_member for uclass membership
dm: Embed struct uclass_member in struct udevice
dm: core: Add uclass-adjunct data structures
dm: core: Add a uclass-adjunct API
dm: core: Integrate adjuncts into existing code paths
dm: core: Add uclass-ID-keyed accessors for priv and plat
dm: core: Add static adjunct declarations for drivers
dm: test: Add tests for uclass adjuncts
doc: dm: Document uclass adjunct support
sysreset: Use device_get_uclass_ops() for adjunct support
power: pmic: raa215300: Convert sysreset to uclass adjunct
arch/arm/mach-rockchip/board.c | 2 +-
arch/arm/mach-rockchip/rk3288/syscon_rk3288.c | 8 +-
arch/sandbox/dts/test.dts | 4 +
board/nuvoton/poleg_evb/poleg_evb.c | 4 +-
board/theobroma-systems/common/common.c | 4 +-
cmd/rng.c | 2 +-
cmd/w1.c | 4 +-
doc/develop/driver-model/design.rst | 134 ++++++
drivers/core/Kconfig | 10 +
drivers/core/Makefile | 1 +
drivers/core/adjunct.c | 249 ++++++++++
drivers/core/device-remove.c | 13 +-
drivers/core/device.c | 72 ++-
drivers/core/dump.c | 6 +-
drivers/core/read.c | 2 +-
drivers/core/uclass.c | 314 ++++++++++--
drivers/i2c/ast2600_i2c.c | 2 +-
drivers/i2c/npcm_i2c.c | 2 +-
drivers/misc/test_drv.c | 35 +-
drivers/mmc/octeontx_hsmmc.c | 2 +-
drivers/pci/pci-emul-uclass.c | 4 +-
drivers/pci/pci-uclass.c | 2 +-
drivers/pci/pcie_mediatek_gen3.c | 4 +-
drivers/pinctrl/pinctrl-uclass.c | 2 +-
drivers/power/pmic/raa215300.c | 60 ++-
drivers/serial/serial_s5p4418_pl011.c | 2 +-
drivers/spi/spi-uclass.c | 4 +-
drivers/sysreset/Kconfig | 3 +
drivers/sysreset/Makefile | 1 -
drivers/sysreset/sysreset_raa215300.c | 58 ---
drivers/usb/host/ehci-mx6.c | 2 +-
drivers/usb/host/usb-uclass.c | 2 +-
drivers/video/video-uclass.c | 4 +-
include/dm/device-internal.h | 186 ++++++-
include/dm/device.h | 156 +++++-
include/dm/read.h | 2 +-
include/dm/uclass-internal.h | 8 +
include/dm/uclass.h | 214 +++++++-
include/linker_lists.h | 25 +-
include/sysreset.h | 9 +-
lib/efi_loader/efi_device_path.c | 4 +-
net/eth-uclass.c | 2 +-
test/dm/Makefile | 1 +
test/dm/adjunct.c | 455 ++++++++++++++++++
test/dm/bus.c | 21 +-
test/dm/core.c | 8 +-
test/dm/test-fdt.c | 39 +-
test/dm/test-uclass.c | 8 +-
tools/dtoc/dtb_platdata.py | 34 +-
tools/dtoc/test_dtoc.py | 121 +++--
50 files changed, 1999 insertions(+), 312 deletions(-)
create mode 100644 drivers/core/adjunct.c
delete mode 100644 drivers/sysreset/sysreset_raa215300.c
create mode 100644 test/dm/adjunct.c
--
2.43.0
base-commit: eb00c710508d09b2a3b9aca75dd18280f1304703
branch: dmc-us
More information about the U-Boot
mailing list