mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-04 04:51:53 +00:00
[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 <2743257167@qq.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-06-04 GuEe-GUI the first version
|
||||
* 2025-12-25 lhxj fix OFW bus conflict and prevent duplicate device creation
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
@@ -223,16 +224,14 @@ rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np)
|
||||
|
||||
if (dev)
|
||||
{
|
||||
/* Was create */
|
||||
if (dev->drv)
|
||||
{
|
||||
/* Was probe OK */
|
||||
err = RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = rt_bus_reload_driver_device(dev->bus, dev);
|
||||
}
|
||||
/*
|
||||
* Device was already created (np->dev != NULL).
|
||||
* - If it's already probed (dev->drv != NULL), nothing to do.
|
||||
* - If not yet probed (dev->drv == NULL), it belongs to its native bus
|
||||
* (e.g. I2C/SPI) which will handle probing; platform bus should not reload
|
||||
* or transfer it, to avoid cross-bus conflicts.
|
||||
*/
|
||||
err = RT_EOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-12-06 GuEe-GUI first version
|
||||
* 2025-12-25 lhxj mark OFW node as taken to prevent platform bus duplication
|
||||
*/
|
||||
|
||||
#include <rtdevice.h>
|
||||
@@ -63,6 +64,9 @@ void i2c_bus_scan_clients(struct rt_i2c_bus_device *bus)
|
||||
|
||||
rt_dm_dev_set_name(&client->parent, "%s", client->name);
|
||||
|
||||
/* Mark this OFW node as taken to prevent platform bus from creating duplicate device */
|
||||
i2c_client_np->dev = &client->parent;
|
||||
|
||||
rt_i2c_device_register(client);
|
||||
|
||||
if (i2c_client_np != child_np)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-12-06 GuEe-GUI first version
|
||||
* 2025-12-25 lhxj mark OFW node as taken to prevent platform bus duplication; fix cppcheck warning
|
||||
*/
|
||||
|
||||
#include "dev_spi_dm.h"
|
||||
@@ -69,6 +70,9 @@ void spi_bus_scan_devices(struct rt_spi_bus *bus)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Mark this OFW node as taken to prevent platform bus from creating duplicate device */
|
||||
spi_dev_np->dev = &spi_dev->parent;
|
||||
|
||||
rt_spi_device_register(spi_dev);
|
||||
}
|
||||
}
|
||||
@@ -163,7 +167,7 @@ static rt_err_t spi_probe(rt_device_t dev)
|
||||
rt_spidev_device_init(device, rt_dm_dev_get_name(&device->parent));
|
||||
}
|
||||
|
||||
return err;
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t spi_remove(rt_device_t dev)
|
||||
|
||||
Reference in New Issue
Block a user