X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fcore%2Fdevice.c;h=a7408d9c76c61aa451833145d23644888633a9aa;hb=64b69f8c89352975c25730bcca4bf8af2296297f;hp=9f39218423e1e1f9b4d734d3d4a73d9f9b9ed710;hpb=d6b92b9742f125542dd0985976c3a6c560ed40fd;p=oweals%2Fu-boot.git diff --git a/drivers/core/device.c b/drivers/core/device.c index 9f39218423..a7408d9c76 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -143,11 +145,9 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, goto fail_alloc3; } } - } - - /* put dev into parent's successor list */ - if (parent) + /* put dev into parent's successor list */ list_add_tail(&dev->sibling_node, &parent->child_head); + } ret = uclass_bind_device(dev); if (ret) @@ -323,6 +323,22 @@ int device_ofdata_to_platdata(struct udevice *dev) if (dev->flags & DM_FLAG_PLATDATA_VALID) return 0; + /* Ensure all parents have ofdata */ + if (dev->parent) { + ret = device_ofdata_to_platdata(dev->parent); + if (ret) + goto fail; + + /* + * The device might have already been probed during + * the call to device_probe() on its parent device + * (e.g. PCI bridge devices). Test the flags again + * so that we don't mess up the device. + */ + if (dev->flags & DM_FLAG_PLATDATA_VALID) + return 0; + } + drv = dev->driver; assert(drv); @@ -591,7 +607,8 @@ static int device_find_by_ofnode(ofnode node, struct udevice **devp) } #endif -int device_get_child(struct udevice *parent, int index, struct udevice **devp) +int device_get_child(const struct udevice *parent, int index, + struct udevice **devp) { struct udevice *dev; @@ -603,7 +620,7 @@ int device_get_child(struct udevice *parent, int index, struct udevice **devp) return -ENODEV; } -int device_get_child_count(struct udevice *parent) +int device_get_child_count(const struct udevice *parent) { struct udevice *dev; int count = 0; @@ -614,7 +631,7 @@ int device_get_child_count(struct udevice *parent) return count; } -int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, +int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq, bool find_req_seq, struct udevice **devp) { struct udevice *dev; @@ -634,7 +651,7 @@ int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, return -ENODEV; } -int device_get_child_by_seq(struct udevice *parent, int seq, +int device_get_child_by_seq(const struct udevice *parent, int seq, struct udevice **devp) { struct udevice *dev; @@ -652,7 +669,7 @@ int device_get_child_by_seq(struct udevice *parent, int seq, return device_get_device_tail(dev, ret, devp); } -int device_find_child_by_of_offset(struct udevice *parent, int of_offset, +int device_find_child_by_of_offset(const struct udevice *parent, int of_offset, struct udevice **devp) { struct udevice *dev; @@ -669,7 +686,7 @@ int device_find_child_by_of_offset(struct udevice *parent, int of_offset, return -ENODEV; } -int device_get_child_by_of_offset(struct udevice *parent, int node, +int device_get_child_by_of_offset(const struct udevice *parent, int node, struct udevice **devp) { struct udevice *dev; @@ -712,7 +729,7 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp) return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp); } -int device_find_first_child(struct udevice *parent, struct udevice **devp) +int device_find_first_child(const struct udevice *parent, struct udevice **devp) { if (list_empty(&parent->child_head)) { *devp = NULL; @@ -739,7 +756,7 @@ int device_find_next_child(struct udevice **devp) return 0; } -int device_find_first_inactive_child(struct udevice *parent, +int device_find_first_inactive_child(const struct udevice *parent, enum uclass_id uclass_id, struct udevice **devp) { @@ -757,7 +774,7 @@ int device_find_first_inactive_child(struct udevice *parent, return -ENODEV; } -int device_find_first_child_by_uclass(struct udevice *parent, +int device_find_first_child_by_uclass(const struct udevice *parent, enum uclass_id uclass_id, struct udevice **devp) { @@ -774,7 +791,7 @@ int device_find_first_child_by_uclass(struct udevice *parent, return -ENODEV; } -int device_find_child_by_name(struct udevice *parent, const char *name, +int device_find_child_by_name(const struct udevice *parent, const char *name, struct udevice **devp) { struct udevice *dev; @@ -791,6 +808,64 @@ int device_find_child_by_name(struct udevice *parent, const char *name, return -ENODEV; } +int device_first_child_err(struct udevice *parent, struct udevice **devp) +{ + struct udevice *dev; + + device_find_first_child(parent, &dev); + if (!dev) + return -ENODEV; + + return device_get_device_tail(dev, 0, devp); +} + +int device_next_child_err(struct udevice **devp) +{ + struct udevice *dev = *devp; + + device_find_next_child(&dev); + if (!dev) + return -ENODEV; + + return device_get_device_tail(dev, 0, devp); +} + +int device_first_child_ofdata_err(struct udevice *parent, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + device_find_first_child(parent, &dev); + if (!dev) + return -ENODEV; + + ret = device_ofdata_to_platdata(dev); + if (ret) + return ret; + + *devp = dev; + + return 0; +} + +int device_next_child_ofdata_err(struct udevice **devp) +{ + struct udevice *dev = *devp; + int ret; + + device_find_next_child(&dev); + if (!dev) + return -ENODEV; + + ret = device_ofdata_to_platdata(dev); + if (ret) + return ret; + + *devp = dev; + + return 0; +} + struct udevice *dev_get_parent(const struct udevice *child) { return child->parent; @@ -827,7 +902,7 @@ bool device_has_children(const struct udevice *dev) return !list_empty(&dev->child_head); } -bool device_has_active_children(struct udevice *dev) +bool device_has_active_children(const struct udevice *dev) { struct udevice *child; @@ -841,7 +916,7 @@ bool device_has_active_children(struct udevice *dev) return false; } -bool device_is_last_sibling(struct udevice *dev) +bool device_is_last_sibling(const struct udevice *dev) { struct udevice *parent = dev->parent; @@ -867,7 +942,7 @@ int device_set_name(struct udevice *dev, const char *name) } #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) -bool device_is_compatible(struct udevice *dev, const char *compat) +bool device_is_compatible(const struct udevice *dev, const char *compat) { return ofnode_device_is_compatible(dev_ofnode(dev), compat); }