cmd: bind: Fix driver binding on a device
Fix a regression brings by commit84f8e36f03
("cmd: bind: allow to bind driver with driver data") As example, the following bind command doesn't work: bind /soc/usb-otg@49000000 usb_ether As usb_ether driver has no compatible string, it can't be find by lists_bind_fdt(). In bind_by_node_path(), which called lists_bind_fdt(), the driver entry is known, pass it to lists_bind_fdt() to force the driver entry selection. For this, add a new parameter struct *driver to lists_bind_fdt(). Fix also all lists_bind_fdt() callers. Fixes:84f8e36f03
("cmd: bind: allow to bind driver with driver data") Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> Reported-by: Herbert Poetzl <herbert@13thfloor.at> Cc: Marek Vasut <marex@denx.de> Cc: Herbert Poetzl <herbert@13thfloor.at> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
089e433e56
commit
38f7d3b653
@ -32,7 +32,7 @@ void spl_board_init(void)
|
|||||||
offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "nxp,imx8-pd");
|
offset = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "nxp,imx8-pd");
|
||||||
while (offset != -FDT_ERR_NOTFOUND) {
|
while (offset != -FDT_ERR_NOTFOUND) {
|
||||||
lists_bind_fdt(gd->dm_root, offset_to_ofnode(offset),
|
lists_bind_fdt(gd->dm_root, offset_to_ofnode(offset),
|
||||||
NULL, true);
|
NULL, NULL, true);
|
||||||
offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
|
offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
|
||||||
"nxp,imx8-pd");
|
"nxp,imx8-pd");
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ static int bind_by_node_path(const char *path, const char *drv_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ofnode = ofnode_path(path);
|
ofnode = ofnode_path(path);
|
||||||
ret = lists_bind_fdt(parent, ofnode, &dev, false);
|
ret = lists_bind_fdt(parent, ofnode, &dev, drv, false);
|
||||||
|
|
||||||
if (!dev || ret) {
|
if (!dev || ret) {
|
||||||
printf("Unable to bind. err:%d\n", ret);
|
printf("Unable to bind. err:%d\n", ret);
|
||||||
|
@ -1135,7 +1135,7 @@ int dev_enable_by_path(const char *path)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return lists_bind_fdt(parent, node, NULL, false);
|
return lists_bind_fdt(parent, node, NULL, NULL, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ static int driver_check_compatible(const struct udevice_id *of_match,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
||||||
bool pre_reloc_only)
|
struct driver *drv, bool pre_reloc_only)
|
||||||
{
|
{
|
||||||
struct driver *driver = ll_entry_start(struct driver, driver);
|
struct driver *driver = ll_entry_start(struct driver, driver);
|
||||||
const int n_ents = ll_entry_count(struct driver, driver);
|
const int n_ents = ll_entry_count(struct driver, driver);
|
||||||
@ -225,6 +225,8 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
|||||||
for (entry = driver; entry != driver + n_ents; entry++) {
|
for (entry = driver; entry != driver + n_ents; entry++) {
|
||||||
ret = driver_check_compatible(entry->of_match, &id,
|
ret = driver_check_compatible(entry->of_match, &id,
|
||||||
compat);
|
compat);
|
||||||
|
if ((drv) && (drv == entry))
|
||||||
|
break;
|
||||||
if (!ret)
|
if (!ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ static int dm_scan_fdt_node(struct udevice *parent, ofnode parent_node,
|
|||||||
pr_debug(" - ignoring disabled device\n");
|
pr_debug(" - ignoring disabled device\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
err = lists_bind_fdt(parent, node, NULL, pre_reloc_only);
|
err = lists_bind_fdt(parent, node, NULL, NULL, pre_reloc_only);
|
||||||
if (err && !ret) {
|
if (err && !ret) {
|
||||||
ret = err;
|
ret = err;
|
||||||
debug("%s: ret=%d\n", node_name, ret);
|
debug("%s: ret=%d\n", node_name, ret);
|
||||||
|
@ -219,7 +219,7 @@ static int imx8_scu_bind(struct udevice *dev)
|
|||||||
|
|
||||||
debug("%s(dev=%p)\n", __func__, dev);
|
debug("%s(dev=%p)\n", __func__, dev);
|
||||||
ofnode_for_each_subnode(node, dev_ofnode(dev)) {
|
ofnode_for_each_subnode(node, dev_ofnode(dev)) {
|
||||||
ret = lists_bind_fdt(dev, node, &child, true);
|
ret = lists_bind_fdt(dev, node, &child, NULL, true);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
debug("bind child dev %s\n", child->name);
|
debug("bind child dev %s\n", child->name);
|
||||||
|
@ -69,7 +69,7 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
|
|||||||
* anyway.
|
* anyway.
|
||||||
*/
|
*/
|
||||||
if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
|
if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
|
||||||
devp, false)) {
|
devp, NULL, false)) {
|
||||||
if (!device_probe(*devp))
|
if (!device_probe(*devp))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ int notrace dm_timer_init(void)
|
|||||||
* If the timer is not marked to be bound before
|
* If the timer is not marked to be bound before
|
||||||
* relocation, bind it anyway.
|
* relocation, bind it anyway.
|
||||||
*/
|
*/
|
||||||
if (!lists_bind_fdt(dm_root(), node, &dev, false)) {
|
if (!lists_bind_fdt(dm_root(), node, &dev, NULL, false)) {
|
||||||
ret = device_probe(dev);
|
ret = device_probe(dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -53,13 +53,14 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
|
|||||||
* @parent: parent device (root)
|
* @parent: parent device (root)
|
||||||
* @node: device tree node to bind
|
* @node: device tree node to bind
|
||||||
* @devp: if non-NULL, returns a pointer to the bound device
|
* @devp: if non-NULL, returns a pointer to the bound device
|
||||||
|
* @drv: if non-NULL, force this driver to be bound
|
||||||
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
* @pre_reloc_only: If true, bind only nodes with special devicetree properties,
|
||||||
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
* or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers.
|
||||||
* @return 0 if device was bound, -EINVAL if the device tree is invalid,
|
* @return 0 if device was bound, -EINVAL if the device tree is invalid,
|
||||||
* other -ve value on error
|
* other -ve value on error
|
||||||
*/
|
*/
|
||||||
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
|
||||||
bool pre_reloc_only);
|
struct driver *drv, bool pre_reloc_only);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* device_bind_driver() - bind a device to a driver
|
* device_bind_driver() - bind a device to a driver
|
||||||
|
@ -25,7 +25,7 @@ static int noptest_bind(struct udevice *parent)
|
|||||||
const char *bind_flag = ofnode_read_string(ofnode, "bind");
|
const char *bind_flag = ofnode_read_string(ofnode, "bind");
|
||||||
|
|
||||||
if (bind_flag && (strcmp(bind_flag, "True") == 0))
|
if (bind_flag && (strcmp(bind_flag, "True") == 0))
|
||||||
lists_bind_fdt(parent, ofnode, &dev, false);
|
lists_bind_fdt(parent, ofnode, &dev, NULL, false);
|
||||||
ofnode = dev_read_next_subnode(ofnode);
|
ofnode = dev_read_next_subnode(ofnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user