Skip to content

Commit 5b18fe8

Browse files
committed
[drivers] Fix OFW bus conflict and prevent duplicate device creation
Problem: When enumerating device tree nodes, platform bus and native buses (I2C/SPI) may create duplicate devices for the same OFW node, causing cross-bus conflicts. This triggers assertion failure '(dev->bus != new_bus)' in rt_bus_reload_driver_device() during boot on minimal DM-enabled systems. Root Cause: 1. Platform bus tries to reload devices that already belong to other buses by calling rt_bus_reload_driver_device(dev->bus, dev), which violates the API contract (requires dev->bus != new_bus). 2. Native buses (I2C/SPI) do not mark OFW nodes as occupied, so platform bus creates duplicate platform devices for I2C/SPI client nodes. Solution: 1. components/drivers/core/platform_ofw.c: Return RT_EOK when np->dev exists, letting the native bus handle device lifecycle instead of cross-bus reload. 2. components/drivers/i2c/dev_i2c_bus.c: Mark i2c_client_np->dev during scan to prevent platform bus from duplicating I2C client devices. 3. components/drivers/spi/dev_spi_bus.c: Mark spi_dev_np->dev during scan to prevent platform bus from duplicating SPI devices. Tested on Spacemit K1 RISC-V platform with minimal DM configuration. Signed-off-by: lhxj <[email protected]>
1 parent 754d517 commit 5b18fe8

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

components/drivers/core/platform_ofw.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2023-06-04 GuEe-GUI the first version
9+
* 2025-12-25 lhxj fix OFW bus conflict and prevent duplicate device creation
910
*/
1011

1112
#include <rtthread.h>
@@ -223,16 +224,14 @@ rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np)
223224

224225
if (dev)
225226
{
226-
/* Was create */
227-
if (dev->drv)
228-
{
229-
/* Was probe OK */
230-
err = RT_EOK;
231-
}
232-
else
233-
{
234-
err = rt_bus_reload_driver_device(dev->bus, dev);
235-
}
227+
/*
228+
* Device was already created (np->dev != NULL).
229+
* - If it's already probed (dev->drv != NULL), nothing to do.
230+
* - If not yet probed (dev->drv == NULL), it belongs to its native bus
231+
* (e.g. I2C/SPI) which will handle probing; platform bus should not reload
232+
* or transfer it, to avoid cross-bus conflicts.
233+
*/
234+
err = RT_EOK;
236235
}
237236
else
238237
{

components/drivers/i2c/dev_i2c_bus.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2022-12-06 GuEe-GUI first version
9+
* 2025-12-25 lhxj mark OFW node as taken to prevent platform bus duplication
910
*/
1011

1112
#include <rtdevice.h>
@@ -63,6 +64,9 @@ void i2c_bus_scan_clients(struct rt_i2c_bus_device *bus)
6364

6465
rt_dm_dev_set_name(&client->parent, "%s", client->name);
6566

67+
/* Mark this OFW node as taken to prevent platform bus from creating duplicate device */
68+
i2c_client_np->dev = &client->parent;
69+
6670
rt_i2c_device_register(client);
6771

6872
if (i2c_client_np != child_np)

components/drivers/spi/dev_spi_bus.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2022-12-06 GuEe-GUI first version
9+
* 2025-12-25 lhxj mark OFW node as taken to prevent platform bus duplication; fix cppcheck warning
910
*/
1011

1112
#include "dev_spi_dm.h"
@@ -69,6 +70,9 @@ void spi_bus_scan_devices(struct rt_spi_bus *bus)
6970
continue;
7071
}
7172

73+
/* Mark this OFW node as taken to prevent platform bus from creating duplicate device */
74+
spi_dev_np->dev = &spi_dev->parent;
75+
7276
rt_spi_device_register(spi_dev);
7377
}
7478
}
@@ -163,7 +167,7 @@ static rt_err_t spi_probe(rt_device_t dev)
163167
rt_spidev_device_init(device, rt_dm_dev_get_name(&device->parent));
164168
}
165169

166-
return err;
170+
return RT_EOK;
167171
}
168172

169173
static rt_err_t spi_remove(rt_device_t dev)

0 commit comments

Comments
 (0)