X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fcore%2Fdevice.c;h=8eabaf8b553219bea677d9a9c1be134ba57c5e0a;hb=bb1bb4bb5df9df4d3f07e39a632daaff79e4b77e;hp=5176aa3f866f49a422a0dba715237144ad5039cd;hpb=e6cd05e5025bbab9723bbb09c506cbb5aa63bc53;p=oweals%2Fu-boot.git diff --git a/drivers/core/device.c b/drivers/core/device.c index 5176aa3f86..8eabaf8b55 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,16 @@ 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); - } +#if CONFIG_IS_ENABLED(OF_PRIOR_STAGE) + if (dev->req_seq == -1) + dev->req_seq = + uclass_find_next_free_req_seq(drv->id); +#endif + } else { + dev->req_seq = uclass_find_next_free_req_seq(drv->id); } } @@ -305,7 +312,6 @@ static void *alloc_priv(int size, uint flags) int device_probe(struct udevice *dev) { - struct power_domain pd; const struct driver *drv; int size = 0; int ret; @@ -386,9 +392,12 @@ int device_probe(struct udevice *dev) if (dev->parent && device_get_uclass_id(dev) != UCLASS_PINCTRL) pinctrl_select_state(dev, "default"); - if (dev->parent && device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) { - if (!power_domain_get(dev, &pd)) - power_domain_on(&pd); + if (CONFIG_IS_ENABLED(POWER_DOMAIN) && dev->parent && + (device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) && + !(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF)) { + ret = dev_power_domain_on(dev); + if (ret) + goto fail; } ret = uclass_pre_probe_device(dev); @@ -401,16 +410,23 @@ int device_probe(struct udevice *dev) goto fail; } - if (drv->ofdata_to_platdata && dev_has_of_node(dev)) { + if (drv->ofdata_to_platdata && + (CONFIG_IS_ENABLED(OF_PLATDATA) || dev_has_of_node(dev))) { ret = drv->ofdata_to_platdata(dev); if (ret) goto fail; } - /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ - ret = clk_set_defaults(dev); - if (ret) - goto fail; + /* Only handle devices that have a valid ofnode */ + if (dev_of_valid(dev)) { + /* + * Process 'assigned-{clocks/clock-parents/clock-rates}' + * properties + */ + ret = clk_set_defaults(dev, 0); + if (ret) + goto fail; + } if (drv->probe) { ret = drv->probe(dev); @@ -517,6 +533,7 @@ static int device_get_device_tail(struct udevice *dev, int ret, return 0; } +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) /** * device_find_by_ofnode() - Return device associated with given ofnode * @@ -543,6 +560,7 @@ static int device_find_by_ofnode(ofnode node, struct udevice **devp) return -ENODEV; } +#endif int device_get_child(struct udevice *parent, int index, struct udevice **devp) { @@ -556,6 +574,17 @@ int device_get_child(struct udevice *parent, int index, struct udevice **devp) return -ENODEV; } +int device_get_child_count(struct udevice *parent) +{ + struct udevice *dev; + int count = 0; + + list_for_each_entry(dev, &parent->child_head, sibling_node) + count++; + + return count; +} + int device_find_child_by_seq(struct udevice *parent, int seq_or_req_seq, bool find_req_seq, struct udevice **devp) { @@ -699,6 +728,40 @@ int device_find_first_inactive_child(struct udevice *parent, return -ENODEV; } +int device_find_first_child_by_uclass(struct udevice *parent, + enum uclass_id uclass_id, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (device_get_uclass_id(dev) == uclass_id) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + +int device_find_child_by_name(struct udevice *parent, const char *name, + struct udevice **devp) +{ + struct udevice *dev; + + *devp = NULL; + + list_for_each_entry(dev, &parent->child_head, sibling_node) { + if (!strcmp(dev->name, name)) { + *devp = dev; + return 0; + } + } + + return -ENODEV; +} + struct udevice *dev_get_parent(const struct udevice *child) { return child->parent; @@ -774,6 +837,7 @@ int device_set_name(struct udevice *dev, const char *name) return 0; } +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) bool device_is_compatible(struct udevice *dev, const char *compat) { return ofnode_device_is_compatible(dev_ofnode(dev), compat); @@ -834,5 +898,6 @@ int dev_enable_by_path(const char *path) if (ret) return ret; - return lists_bind_fdt(parent, node, NULL); + return lists_bind_fdt(parent, node, NULL, false); } +#endif