cmd: bind: Fix driver binding on a device

Fix a regression brings by commit 84f8e36f03 ("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:
Patrice Chotard 2021-09-10 16:16:20 +02:00
parent 089e433e56
commit 38f7d3b653
10 changed files with 13 additions and 10 deletions

View File

@ -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");
} }

View File

@ -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);

View File

@ -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

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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

View File

@ -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);
} }