![]() |
RT-Thread RTOS
An open source embedded real-time operating system
|
RT-Thread DM binds drivers to devices through **struct rt_bus**: each bus keeps linked lists of devices and drivers, runs **match**, then **probe** / **remove** / **shutdown**. Most SoC drivers use the built-in **platform** bus; other stacks (e.g. RPMsg) register their own bus type on the same core.
Headers: components/drivers/include/drivers/core/bus.h, driver.h. Core: components/drivers/core/bus.c. Reference bus: components/drivers/core/platform.c.
Device-side helpers (rt_dm_dev_iomap, properties, IRQ): Device model helpers (dm.h).
| Option | Role |
|---|---|
**RT_USING_DM** | Enables **bus.c**, **driver.c**, platform bus, and DM helpers |
**RT_USING_DEV_BUS** | Optional **rt_device_bus_create** — bus as **RT_Device_Class_Bus** device |
**RT_USING_OFW** | Platform **match** uses **compatible**; devices carry **dev->ofw_node** |
**RT_USING_PINCTRL** | Platform **probe** applies **pinctrl-*** before driver **probe** |
**RT_USING_CLK** | Platform **probe** runs **rt_ofw_clk_set_defaults** |
Binding (bus.c): **rt_bus_add_device** walks **drv_list**; **rt_bus_add_driver** walks **dev_list**. **match** must succeed before **dev->drv** is set and **bus->probe(dev)** runs. Failed probe clears **dev->drv**.
| Object | Role |
|---|---|
**struct rt_bus** | Bus type and lifecycle hooks |
**struct rt_driver** | Driver on a bus; **ref_count** = bound devices |
**struct rt_platform_device** | Platform device embedding **rt_device** |
| Callback | Contract |
|---|---|
**match** | Pure — no HW access; return **RT_TRUE** to bind |
**probe** | Bus-level setup (platform: pinctrl, clocks, power domain) then driver **probe** |
**remove** | Teardown; platform calls **pdrv->remove** and **rt_platform_ofw_free** |
**shutdown** | Invoked from **rt_bus_shutdown()** on system off |
| API | Role |
|---|---|
**rt_bus_register** | Register bus on global **bus_nodes** |
**rt_bus_add_device / rt_bus_add_driver** | Add node and run matching |
**rt_bus_remove_device / rt_bus_remove_driver** | Remove; driver busy if **ref_count > 0** |
**rt_bus_for_each_dev / rt_bus_for_each_drv** | Iterate under spinlock |
**rt_bus_find_by_name** | Find **"platform"** etc. |
**rt_bus_reload_driver_device** | Move device to another bus |
**rt_bus_shutdown** | Shutdown all devices on all buses |
**rt_driver_register / unregister** | Driver attach/detach |
Example:
**INIT_CORE_EXPORT(platform_bus_init)** registers **name = "platform"**.
rt_ofw_node_match(np, pdrv->ids)** when **dev->ofw_node** is set.pdev->name** and **pdrv->name**.rt_ofw_clk_set_defaults** — Clock framework (CLK)rt_dm_power_domain_attach(dev, RT_TRUE)** — **-RT_EEMPTY** OK — Power domainpdrv->probe(pdev)** — map MMIO, clocks, register **rt_device**| OFW API | Role |
|---|---|
**rt_platform_ofw_request** | Instantiate from DT node |
**rt_platform_ofw_device_probe_child** | Probe children |
**rt_platform_ofw_free** | Free OFW state on remove |
See Platform bus, Open Firmware (OFW).
| New bus when… | Use platform when… |
|---|---|
| Non-OFW enumeration (RPMsg, internal stack bus) | **/soc** MMIO + **compatible** |
Implement **match/probe/remove**, **rt_bus_register** at init, then **rt_bus_add_driver** / **rt_bus_add_device**.
MMC-specific DM: SDIO device model. This page covers **rt_bus / rt_driver** only.
| Topic | Document |
|---|---|
| System shutdown | System power off and reboot (core) |
| Power domains | Power domain |
| Regulators | Regulator |
Typical order: regulator → power domain → clock/reset → rt_dm_dev_iomap.
RT_PLATFORM_DRIVER_EXPORT** (or subsystem **RT_DRIVER_EXPORT**).rt_platform_ofw_request** or manual register.probe**: resources → HW → register functional device; unwind on error.remove**: reverse order; disable IRQ before free.match with side effects** breaks re-probe.rt_bus_add_device without remove.rt_driver_unregister while devices bound** — **-RT_EBUSY**.components/drivers/core/bus.c, platform.c