1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-03 17:52:07 +02:00

dm: uclass: don't assign aliased seq numbers

If there are aliases for an uclass, set the base for the "dynamically"
allocated numbers next to the highest alias.

Please note, that this might lead to holes in the sequences, depending
on the device tree. For example if there is only an alias "ethernet1",
the next device seq number would be 2.

In particular this fixes a problem with boards which are using ethernet
aliases but also might have network add-in cards like the E1000. If the
board is started with the add-in card and depending on the order of the
drivers, the E1000 might occupy the first ethernet device and mess up
all the hardware addresses, because the devices are now shifted by one.

Also adapt the test cases to the new handling and add test cases
checking the holes in the seq numbers.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Alex Marginean <alexandru.marginean@nxp.com>
Tested-by: Alex Marginean <alexandru.marginean@nxp.com>
Acked-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Michal Simek <michal.simek@xilinx.com> [on zcu102-revA]
This commit is contained in:
Michael Walle
2020-06-02 01:47:09 +02:00
committed by Simon Glass
parent 0a6b75f7d8
commit be1a6e9425
5 changed files with 44 additions and 23 deletions

View File

@@ -689,13 +689,14 @@ int uclass_unbind_device(struct udevice *dev)
int uclass_resolve_seq(struct udevice *dev)
{
struct uclass *uc = dev->uclass;
struct uclass_driver *uc_drv = uc->uc_drv;
struct udevice *dup;
int seq;
int seq = 0;
int ret;
assert(dev->seq == -1);
ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq,
false, &dup);
ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup);
if (!ret) {
dm_warn("Device '%s': seq %d is in use by '%s'\n",
dev->name, dev->req_seq, dup->name);
@@ -707,9 +708,17 @@ int uclass_resolve_seq(struct udevice *dev)
return ret;
}
for (seq = 0; seq < DM_MAX_SEQ; seq++) {
ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq,
false, &dup);
if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
(uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
/*
* dev_read_alias_highest_id() will return -1 if there no
* alias. Thus we can always add one.
*/
seq = dev_read_alias_highest_id(uc_drv->name) + 1;
}
for (; seq < DM_MAX_SEQ; seq++) {
ret = uclass_find_device_by_seq(uc_drv->id, seq, false, &dup);
if (ret == -ENODEV)
break;
if (ret)