From: Jean-Jacques Hiblot Date: Fri, 7 Dec 2018 13:50:39 +0000 (+0100) Subject: dm: device: Allow using uclass_find_device_by_seq() without OF_CONTROL X-Git-Url: http://git.dujemihanovic.xyz/img/static/git-logo.png?a=commitdiff_plain;h=3542ff29e4542b8cb0ac3ae861247e9bd487f22f;p=u-boot.git dm: device: Allow using uclass_find_device_by_seq() without OF_CONTROL If OF_CONTROL is not enabled and DM_SEQ_ALIAS is enabled, we must assign an alias (requested sequence number) to devices that belongs to a class with the DM_UC_FLAG_SEQ_ALIAS flag. Otherwise uclass_find_device_by_seq() cannot be used to get/probe a device. In particular i2c_get_chip_for_busnum() cannot be used. Signed-off-by: Jean-Jacques Hiblot Reviewed-by: Simon Glass Reviewed-by: Heiko Schocher --- diff --git a/drivers/core/device.c b/drivers/core/device.c index 836bcadced..0d15e5062b 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -70,7 +70,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, dev->seq = -1; dev->req_seq = -1; - if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS)) { + if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) && + (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) { /* * Some devices, such as a SPI bus, I2C bus and serial ports * are numbered using aliases. @@ -78,10 +79,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, * This is just a 'requested' sequence, and will be * resolved (and ->seq updated) when the device is probed. */ - if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { - if (uc->uc_drv->name && ofnode_valid(node)) { + if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { + if (uc->uc_drv->name && ofnode_valid(node)) dev_read_alias_seq(dev, &dev->req_seq); - } + } else { + dev->req_seq = uclass_find_next_free_req_seq(drv->id); } } diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 9766aeabd1..a622f07941 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -269,6 +269,30 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name, return -ENODEV; } +#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA) +int uclass_find_next_free_req_seq(enum uclass_id id) +{ + struct uclass *uc; + struct udevice *dev; + int ret; + int max = -1; + + ret = uclass_get(id, &uc); + if (ret) + return ret; + + list_for_each_entry(dev, &uc->dev_head, uclass_node) { + if ((dev->req_seq != -1) && (dev->req_seq > max)) + max = dev->req_seq; + } + + if (max == -1) + return 0; + + return max + 1; +} +#endif + int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, bool find_req_seq, struct udevice **devp) { diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index 8a4839ee88..6977995246 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -11,6 +11,19 @@ #include +/** + * uclass_find_next_free_req_seq() - Get the next free req_seq number + * + * This returns the next free req_seq number. This is useful only if + * OF_CONTROL is not used. The next free req_seq number is simply the + * maximum req_seq of the uclass + 1. + * This allows assiging req_seq number in the binding order. + * + * @id: Id number of the uclass + * @return The next free req_seq number + */ +int uclass_find_next_free_req_seq(enum uclass_id id); + /** * uclass_get_device_tail() - handle the end of a get_device call *