diff --git a/components/drivers/core/bus.c b/components/drivers/core/bus.c index 72ff49628df..659c2fbe63b 100644 --- a/components/drivers/core/bus.c +++ b/components/drivers/core/bus.c @@ -241,6 +241,29 @@ static int bus_probe_device(rt_driver_t drv, void *dev_ptr) return err; } +/** + * @brief Retry matching an unbound device against the drivers on its bus + * + * @param dev the device to probe + * + * @return RT_EOK if the device is already bound or a probe succeeds + */ +rt_err_t rt_bus_probe_device(rt_device_t dev) +{ + if (!dev || !dev->bus) + { + return -RT_EINVAL; + } + + if (dev->drv) + { + return RT_EOK; + } + + return rt_bus_for_each_drv(dev->bus, dev, bus_probe_device); +} +RTM_EXPORT(rt_bus_probe_device); + /** * @brief This function add a driver to the drv_list of a specific bus * diff --git a/components/drivers/core/platform_ofw.c b/components/drivers/core/platform_ofw.c index d617f112fad..4bc2deed5d9 100644 --- a/components/drivers/core/platform_ofw.c +++ b/components/drivers/core/platform_ofw.c @@ -227,14 +227,22 @@ rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np) /* * 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. + * - Retry only devices created by the OFW platform scanner. Other + * devices belong to their native bus (e.g. I2C/SPI) and must not + * be transferred to or probed through the platform bus. */ - err = RT_EOK; + if (!dev->drv && rt_ofw_node_test_flag(np, RT_OFW_F_PLATFORM)) + { + err = rt_bus_probe_device(dev); + } + else + { + err = RT_EOK; + } } else { + struct rt_ofw_node_id *id; struct rt_platform_device *pdev = alloc_ofw_platform_device(np); if (pdev) @@ -244,6 +252,16 @@ rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np) LOG_D("%s register to bus", np->full_name); err = rt_platform_device_register(pdev); + + if (!err && np->child && (id = rt_ofw_node_match(np, platform_ofw_ids))) + { + rt_err_t sub_err; + + if ((sub_err = platform_ofw_device_probe_once(np))) + { + LOG_W("%s child platform device probe failed", np->full_name); + } + } } else { diff --git a/components/drivers/include/drivers/core/bus.h b/components/drivers/include/drivers/core/bus.h index ab821240bb9..bef8421eafc 100644 --- a/components/drivers/include/drivers/core/bus.h +++ b/components/drivers/include/drivers/core/bus.h @@ -41,6 +41,7 @@ rt_err_t rt_bus_for_each_drv(rt_bus_t bus, void *data, int (*fn)(rt_driver_t drv rt_err_t rt_bus_add_driver(rt_bus_t bus, rt_driver_t drv); rt_err_t rt_bus_add_device(rt_bus_t bus, rt_device_t dev); +rt_err_t rt_bus_probe_device(rt_device_t dev); rt_err_t rt_bus_remove_driver(rt_driver_t drv); rt_err_t rt_bus_remove_device(rt_device_t dev);