Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions components/drivers/core/platform_ofw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的目的是为了舍弃之前匹配上的驱动,重新根据设备状态进行驱动匹配,看上去并没有影响 I2C/SPI 呀,如果会发生错误,那应该是调用方的方法不对。

Copy link
Contributor Author

@lhxj lhxj Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

查阅 rt_bus_reload_driver_device 的底层实现,发现内核断言严格禁止了这种操作。说明这个函数本身是为了“跨总线迁移”设计的,不支持“同总线重载”。
image

  1. API 的限制:在 rt_bus_reload_driver_device 函数内部,存在如下断言: RT_ASSERT(dev->bus != new_bus); 当前代码执行 rt_bus_reload_driver_device(dev->bus, dev) 时,将当前总线作为新总线传入。这会直接触发断言失败,程序根本没机会执行后续的匹配逻辑。
  2. 之前的初始化时序可能使得 pinctrl 驱动在被请求前就已经加载完成了。此时 dev->drv 不为空,代码走了 if 分支,从而避开了这个有 Bug 的 else 分支。
image image
  1. 而当在任何时序稍有变动的场景中,若pinctrl 被请求时驱动尚未加载 (drv == NULL)。代码则会掉入 else 分支并触发崩溃。

}
/*
* 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
{
Expand Down
4 changes: 4 additions & 0 deletions components/drivers/i2c/dev_i2c_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion components/drivers/spi/dev_spi_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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)
Expand Down