dm: device: Allow using uclass_find_device_by_seq() without OF_CONTROL
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Fri, 7 Dec 2018 13:50:39 +0000 (14:50 +0100)
committerHeiko Schocher <hs@denx.de>
Mon, 10 Dec 2018 05:05:32 +0000 (06:05 +0100)
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 <jjhiblot@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heiko Schocher <hs@denx.de>
drivers/core/device.c
drivers/core/uclass.c
include/dm/uclass-internal.h

index 836bcadced508ddc0864827c0f0a5e8d1ca41bd3..0d15e5062b66123cd364bd9803e076db7e7dd97c 100644 (file)
@@ -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);
                }
        }
 
index 9766aeabd192f69206f5fec8bb8274979aa14edb..a622f079410c73059a2e4e4d28af1cac4c6f7523 100644 (file)
@@ -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)
 {
index 8a4839ee882830484195974e96a3924cb4d11c8b..6977995246da138e394c553807ea65dd704ba01a 100644 (file)
 
 #include <dm/ofnode.h>
 
+/**
+ * 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
  *