Merge git://git.denx.de/u-boot-dm
[oweals/u-boot.git] / drivers / core / device.c
index ef41a9be3edc3d9cb20247f5026bd720a265d5a7..49faa29dc1a0eecaa84e76371b8301c2eef14d7b 100644 (file)
@@ -109,6 +109,8 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
        dev->seq = -1;
 #ifdef CONFIG_OF_CONTROL
        dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1);
+       if (!IS_ERR_VALUE(dev->req_seq))
+               dev->req_seq &= INT_MAX;
        if (uc->uc_drv->name && of_offset != -1) {
                fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset,
                                     &dev->req_seq);
@@ -230,7 +232,7 @@ static void device_free(struct udevice *dev)
        }
 }
 
-int device_probe(struct udevice *dev)
+int device_probe_child(struct udevice *dev, void *parent_priv)
 {
        struct driver *drv;
        int size = 0;
@@ -280,6 +282,8 @@ int device_probe(struct udevice *dev)
                                ret = -ENOMEM;
                                goto fail;
                        }
+                       if (parent_priv)
+                               memcpy(dev->parent_priv, parent_priv, size);
                }
 
                ret = device_probe(dev->parent);
@@ -333,6 +337,11 @@ fail:
        return ret;
 }
 
+int device_probe(struct udevice *dev)
+{
+       return device_probe_child(dev, NULL);
+}
+
 int device_remove(struct udevice *dev)
 {
        struct driver *drv;
@@ -512,3 +521,30 @@ int device_get_child_by_of_offset(struct udevice *parent, int seq,
        ret = device_find_child_by_of_offset(parent, seq, &dev);
        return device_get_device_tail(dev, ret, devp);
 }
+
+int device_find_first_child(struct udevice *parent, struct udevice **devp)
+{
+       if (list_empty(&parent->child_head)) {
+               *devp = NULL;
+       } else {
+               *devp = list_first_entry(&parent->child_head, struct udevice,
+                                        sibling_node);
+       }
+
+       return 0;
+}
+
+int device_find_next_child(struct udevice **devp)
+{
+       struct udevice *dev = *devp;
+       struct udevice *parent = dev->parent;
+
+       if (list_is_last(&dev->sibling_node, &parent->child_head)) {
+               *devp = NULL;
+       } else {
+               *devp = list_entry(dev->sibling_node.next, struct udevice,
+                                  sibling_node);
+       }
+
+       return 0;
+}