diff --git a/drivers/core/device.c b/drivers/core/device.c index 22d80694cd..8d1287f9a1 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -41,6 +41,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, struct udevice *dev; struct uclass *uc; int size, ret = 0; + bool auto_seq = true; if (devp) *devp = NULL; @@ -73,6 +74,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, dev->seq = -1; dev->req_seq = -1; + dev->sqq = -1; if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) && (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) { /* @@ -84,17 +86,25 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, */ if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { - if (uc->uc_drv->name && ofnode_valid(node)) + if (uc->uc_drv->name && ofnode_valid(node)) { + dev_read_alias_seq(dev, &dev->sqq); dev_read_alias_seq(dev, &dev->req_seq); -#if CONFIG_IS_ENABLED(OF_PRIOR_STAGE) - if (dev->req_seq == -1) - dev->req_seq = - uclass_find_next_free_req_seq(uc); -#endif + auto_seq = false; + } + if (CONFIG_IS_ENABLED(OF_PRIOR_STAGE)) { + if (dev->req_seq == -1) { + auto_seq = true; + dev->req_seq = + uclass_find_next_free_req_seq( + uc); + } + } } else { dev->req_seq = uclass_find_next_free_req_seq(uc); } } + if (auto_seq) + dev->sqq = uclass_find_next_free_req_seq(uc); if (drv->plat_auto) { bool alloc = !plat; diff --git a/drivers/core/root.c b/drivers/core/root.c index 672aa7cea7..f2fba5883a 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -311,22 +311,24 @@ int dm_init_and_scan(bool pre_reloc_only) ret = dm_scan_plat(pre_reloc_only); if (ret) { debug("dm_scan_plat() failed: %d\n", ret); - return ret; + goto fail; } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = dm_extended_scan(pre_reloc_only); if (ret) { debug("dm_extended_scan() failed: %d\n", ret); - return ret; + goto fail; } } ret = dm_scan_other(pre_reloc_only); if (ret) - return ret; + goto fail; return 0; +fail: + return ret; } #ifdef CONFIG_ACPIGEN diff --git a/include/dm/device.h b/include/dm/device.h index 7ada7200e3..725e313eac 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -131,6 +131,13 @@ enum { * @child_head: List of children of this device * @sibling_node: Next device in list of all devices * @flags: Flags for this device DM_FLAG_... + * @sqq: Allocated sequence number for this device (-1 = none). This is set up + * when the device is bound and is unique within the device's uclass. If the + * device has an alias in the devicetree then that is used to set the sequence + * number. Otherwise, the next available number is used. Sequence numbers are + * used by certain commands that need device to be numbered (e.g. 'mmc dev') + * + * The following two fields are deprecated: * @req_seq: Requested sequence number for this device (-1 = any) * @seq: Allocated sequence number for this device (-1 = none). This is set up * when the device is probed and will be unique within the device's uclass. @@ -156,6 +163,7 @@ struct udevice { struct list_head child_head; struct list_head sibling_node; uint32_t flags; + int sqq; int req_seq; int seq; #ifdef CONFIG_DEVRES