diff options
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/Kconfig | 16 | ||||
-rw-r--r-- | drivers/core/acpi.c | 2 | ||||
-rw-r--r-- | drivers/core/device-remove.c | 51 | ||||
-rw-r--r-- | drivers/core/device.c | 320 | ||||
-rw-r--r-- | drivers/core/devres.c | 6 | ||||
-rw-r--r-- | drivers/core/dump.c | 14 | ||||
-rw-r--r-- | drivers/core/lists.c | 6 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 12 | ||||
-rw-r--r-- | drivers/core/read.c | 4 | ||||
-rw-r--r-- | drivers/core/regmap.c | 4 | ||||
-rw-r--r-- | drivers/core/root.c | 160 | ||||
-rw-r--r-- | drivers/core/simple-bus.c | 17 | ||||
-rw-r--r-- | drivers/core/simple-pm-bus.c | 2 | ||||
-rw-r--r-- | drivers/core/syscon-uclass.c | 6 | ||||
-rw-r--r-- | drivers/core/uclass.c | 119 |
15 files changed, 359 insertions, 380 deletions
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index ffae6f9795..65a503e76d 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -113,6 +113,22 @@ config SPL_DM_SEQ_ALIAS numbered devices (e.g. serial0 = &serial0). This feature can be disabled if it is not required, to save code space in SPL. +config SPL_DM_INLINE_OFNODE + bool "Inline some ofnode functions which are seldom used in SPL" + depends on SPL_DM + default y + help + This applies to several ofnode functions (see ofnode.h) which are + seldom used. Inlining them can help reduce code size. + +config TPL_DM_INLINE_OFNODE + bool "Inline some ofnode functions which are seldom used in TPL" + depends on TPL_DM + default y + help + This applies to several ofnode functions (see ofnode.h) which are + seldom used. Inlining them can help reduce code size. + config REGMAP bool "Support register maps" depends on DM diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index 63a791f335..0901b9260a 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -269,7 +269,7 @@ int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent, void *start = ctx->current; log_debug("- method %d, %s %p\n", method, parent->name, func); - ret = device_ofdata_to_platdata(parent); + ret = device_of_to_plat(parent); if (ret) return log_msg_ret("ofdata", ret); ret = func(parent, ctx); diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 0924a575f5..7e8f3afb2d 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -69,10 +69,10 @@ int device_unbind(struct udevice *dev) if (!dev) return log_msg_ret("dev", -EINVAL); - if (dev->flags & DM_FLAG_ACTIVATED) + if (dev_get_flags(dev) & DM_FLAG_ACTIVATED) return log_msg_ret("active", -EINVAL); - if (!(dev->flags & DM_FLAG_BOUND)) + if (!(dev_get_flags(dev) & DM_FLAG_BOUND)) return log_msg_ret("not-bound", -EINVAL); drv = dev->driver; @@ -88,17 +88,17 @@ int device_unbind(struct udevice *dev) if (ret) return log_msg_ret("child unbind", ret); - if (dev->flags & DM_FLAG_ALLOC_PDATA) { - free(dev->platdata); - dev->platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_PDATA) { + free(dev_get_plat(dev)); + dev_set_plat(dev, NULL); } - if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { - free(dev->uclass_platdata); - dev->uclass_platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_UCLASS_PDATA) { + free(dev_get_uclass_plat(dev)); + dev_set_uclass_plat(dev, NULL); } - if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { - free(dev->parent_platdata); - dev->parent_platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev_get_parent_plat(dev)); + dev_set_parent_plat(dev, NULL); } ret = uclass_unbind_device(dev); if (ret) @@ -109,7 +109,7 @@ int device_unbind(struct udevice *dev) devres_release_all(dev); - if (dev->flags & DM_FLAG_NAME_ALLOCED) + if (dev_get_flags(dev) & DM_FLAG_NAME_ALLOCED) free((char *)dev->name); free(dev); @@ -124,27 +124,27 @@ void device_free(struct udevice *dev) { int size; - if (dev->driver->priv_auto_alloc_size) { - free(dev->priv); - dev->priv = NULL; + if (dev->driver->priv_auto) { + free(dev_get_priv(dev)); + dev_set_priv(dev, NULL); } - size = dev->uclass->uc_drv->per_device_auto_alloc_size; + size = dev->uclass->uc_drv->per_device_auto; if (size) { - free(dev->uclass_priv); - dev->uclass_priv = NULL; + free(dev_get_uclass_priv(dev)); + dev_set_uclass_priv(dev, NULL); } if (dev->parent) { - size = dev->parent->driver->per_child_auto_alloc_size; + size = dev->parent->driver->per_child_auto; if (!size) { size = dev->parent->uclass->uc_drv-> - per_child_auto_alloc_size; + per_child_auto; } if (size) { - free(dev->parent_priv); - dev->parent_priv = NULL; + free(dev_get_parent_priv(dev)); + dev_set_parent_priv(dev, NULL); } } - dev->flags &= ~DM_FLAG_PLATDATA_VALID; + dev_bic_flags(dev, DM_FLAG_PLATDATA_VALID); devres_release_probe(dev); } @@ -166,7 +166,7 @@ int device_remove(struct udevice *dev, uint flags) if (!dev) return -EINVAL; - if (!(dev->flags & DM_FLAG_ACTIVATED)) + if (!(dev_get_flags(dev) & DM_FLAG_ACTIVATED)) return 0; drv = dev->driver; @@ -207,8 +207,7 @@ int device_remove(struct udevice *dev, uint flags) if (flags_remove(flags, drv->flags)) { device_free(dev); - dev->seq = -1; - dev->flags &= ~DM_FLAG_ACTIVATED; + dev_bic_flags(dev, DM_FLAG_ACTIVATED); } return ret; diff --git a/drivers/core/device.c b/drivers/core/device.c index 4b3dcb3b37..aeab3836ed 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -34,13 +34,15 @@ DECLARE_GLOBAL_DATA_PTR; static int device_bind_common(struct udevice *parent, const struct driver *drv, - const char *name, void *platdata, + const char *name, void *plat, ulong driver_data, ofnode node, - uint of_platdata_size, struct udevice **devp) + uint of_plat_size, struct udevice **devp) { struct udevice *dev; struct uclass *uc; int size, ret = 0; + bool auto_seq = true; + void *ptr; if (devp) *devp = NULL; @@ -63,88 +65,79 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, #ifdef CONFIG_DEVRES INIT_LIST_HEAD(&dev->devres_head); #endif - dev->platdata = platdata; + dev_set_plat(dev, plat); dev->driver_data = driver_data; dev->name = name; - dev->node = node; + dev_set_ofnode(dev, node); dev->parent = parent; dev->driver = drv; dev->uclass = uc; - dev->seq = -1; - dev->req_seq = -1; + dev->seq_ = -1; 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. - * - * This is just a 'requested' sequence, and will be - * resolved (and ->seq updated) when the device is probed. */ 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); + if (uc->uc_drv->name && ofnode_valid(node)) { + if (!dev_read_alias_seq(dev, &dev->seq_)) + auto_seq = false; + } } } + if (auto_seq && !(uc->uc_drv->flags & DM_UC_FLAG_NO_AUTO_SEQ)) + dev->seq_ = uclass_find_next_free_seq(uc); - if (drv->platdata_auto_alloc_size) { - bool alloc = !platdata; + if (drv->plat_auto) { + bool alloc = !plat; if (CONFIG_IS_ENABLED(OF_PLATDATA)) { - if (of_platdata_size) { - dev->flags |= DM_FLAG_OF_PLATDATA; - if (of_platdata_size < - drv->platdata_auto_alloc_size) + if (of_plat_size) { + dev_or_flags(dev, DM_FLAG_OF_PLATDATA); + if (of_plat_size < drv->plat_auto) alloc = true; } } if (alloc) { - dev->flags |= DM_FLAG_ALLOC_PDATA; - dev->platdata = calloc(1, - drv->platdata_auto_alloc_size); - if (!dev->platdata) { + dev_or_flags(dev, DM_FLAG_ALLOC_PDATA); + ptr = calloc(1, drv->plat_auto); + if (!ptr) { ret = -ENOMEM; goto fail_alloc1; } - if (CONFIG_IS_ENABLED(OF_PLATDATA) && platdata) { - memcpy(dev->platdata, platdata, - of_platdata_size); - } + if (CONFIG_IS_ENABLED(OF_PLATDATA) && plat) + memcpy(ptr, plat, of_plat_size); + dev_set_plat(dev, ptr); } } - size = uc->uc_drv->per_device_platdata_auto_alloc_size; + size = uc->uc_drv->per_device_plat_auto; if (size) { - dev->flags |= DM_FLAG_ALLOC_UCLASS_PDATA; - dev->uclass_platdata = calloc(1, size); - if (!dev->uclass_platdata) { + dev_or_flags(dev, DM_FLAG_ALLOC_UCLASS_PDATA); + ptr = calloc(1, size); + if (!ptr) { ret = -ENOMEM; goto fail_alloc2; } + dev_set_uclass_plat(dev, ptr); } if (parent) { - size = parent->driver->per_child_platdata_auto_alloc_size; + size = parent->driver->per_child_plat_auto; if (!size) { - size = parent->uclass->uc_drv-> - per_child_platdata_auto_alloc_size; + size = parent->uclass->uc_drv->per_child_plat_auto; } if (size) { - dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA; - dev->parent_platdata = calloc(1, size); - if (!dev->parent_platdata) { + dev_or_flags(dev, DM_FLAG_ALLOC_PARENT_PDATA); + ptr = calloc(1, size); + if (!ptr) { ret = -ENOMEM; goto fail_alloc3; } + dev_set_parent_plat(dev, ptr); } /* put dev into parent's successor list */ list_add_tail(&dev->sibling_node, &parent->child_head); @@ -176,7 +169,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, if (devp) *devp = dev; - dev->flags |= DM_FLAG_BOUND; + dev_or_flags(dev, DM_FLAG_BOUND); return 0; @@ -200,20 +193,20 @@ fail_bind: fail_uclass_bind: if (CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)) { list_del(&dev->sibling_node); - if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { - free(dev->parent_platdata); - dev->parent_platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev_get_parent_plat(dev)); + dev_set_parent_plat(dev, NULL); } } fail_alloc3: - if (dev->flags & DM_FLAG_ALLOC_UCLASS_PDATA) { - free(dev->uclass_platdata); - dev->uclass_platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_UCLASS_PDATA) { + free(dev_get_uclass_plat(dev)); + dev_set_uclass_plat(dev, NULL); } fail_alloc2: - if (dev->flags & DM_FLAG_ALLOC_PDATA) { - free(dev->platdata); - dev->platdata = NULL; + if (dev_get_flags(dev) & DM_FLAG_ALLOC_PDATA) { + free(dev_get_plat(dev)); + dev_set_plat(dev, NULL); } fail_alloc1: devres_release_all(dev); @@ -233,18 +226,10 @@ int device_bind_with_driver_data(struct udevice *parent, } int device_bind(struct udevice *parent, const struct driver *drv, - const char *name, void *platdata, int of_offset, + const char *name, void *plat, ofnode node, struct udevice **devp) { - return device_bind_common(parent, drv, name, platdata, 0, - offset_to_ofnode(of_offset), 0, devp); -} - -int device_bind_ofnode(struct udevice *parent, const struct driver *drv, - const char *name, void *platdata, ofnode node, - struct udevice **devp) -{ - return device_bind_common(parent, drv, name, platdata, 0, node, 0, + return device_bind_common(parent, drv, name, plat, 0, node, 0, devp); } @@ -252,7 +237,7 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, const struct driver_info *info, struct udevice **devp) { struct driver *drv; - uint platdata_size = 0; + uint plat_size = 0; int ret; drv = lists_driver_lookup_name(info->name); @@ -262,11 +247,10 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only, return -EPERM; #if CONFIG_IS_ENABLED(OF_PLATDATA) - platdata_size = info->platdata_size; + plat_size = info->plat_size; #endif - ret = device_bind_common(parent, drv, info->name, - (void *)info->platdata, 0, ofnode_null(), - platdata_size, devp); + ret = device_bind_common(parent, drv, info->name, (void *)info->plat, 0, + ofnode_null(), plat_size, devp); if (ret) return ret; @@ -339,21 +323,68 @@ static void *alloc_priv(int size, uint flags) return priv; } -int device_ofdata_to_platdata(struct udevice *dev) +/** + * device_alloc_priv() - Allocate priv/plat data required by the device + * + * @dev: Device to process + * @return 0 if OK, -ENOMEM if out of memory + */ +static int device_alloc_priv(struct udevice *dev) +{ + const struct driver *drv; + void *ptr; + int size; + + drv = dev->driver; + assert(drv); + + /* Allocate private data if requested and not reentered */ + if (drv->priv_auto && !dev_get_priv(dev)) { + ptr = alloc_priv(drv->priv_auto, drv->flags); + if (!ptr) + return -ENOMEM; + dev_set_priv(dev, ptr); + } + + /* Allocate private data if requested and not reentered */ + size = dev->uclass->uc_drv->per_device_auto; + if (size && !dev_get_uclass_priv(dev)) { + ptr = alloc_priv(size, dev->uclass->uc_drv->flags); + if (!ptr) + return -ENOMEM; + dev_set_uclass_priv(dev, ptr); + } + + /* Allocate parent data for this child */ + if (dev->parent) { + size = dev->parent->driver->per_child_auto; + if (!size) + size = dev->parent->uclass->uc_drv->per_child_auto; + if (size && !dev_get_parent_priv(dev)) { + ptr = alloc_priv(size, drv->flags); + if (!ptr) + return -ENOMEM; + dev_set_parent_priv(dev, ptr); + } + } + + return 0; +} + +int device_of_to_plat(struct udevice *dev) { const struct driver *drv; - int size = 0; int ret; if (!dev) return -EINVAL; - if (dev->flags & DM_FLAG_PLATDATA_VALID) + if (dev_get_flags(dev) & DM_FLAG_PLATDATA_VALID) return 0; /* Ensure all parents have ofdata */ if (dev->parent) { - ret = device_ofdata_to_platdata(dev->parent); + ret = device_of_to_plat(dev->parent); if (ret) goto fail; @@ -363,56 +394,25 @@ int device_ofdata_to_platdata(struct udevice *dev) * (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) + if (dev_get_flags(dev) & DM_FLAG_PLATDATA_VALID) return 0; } + ret = device_alloc_priv(dev); + if (ret) + goto fail; + drv = dev->driver; assert(drv); - /* Allocate private data if requested and not reentered */ - if (drv->priv_auto_alloc_size && !dev->priv) { - dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags); - if (!dev->priv) { - ret = -ENOMEM; - goto fail; - } - } - /* Allocate private data if requested and not reentered */ - size = dev->uclass->uc_drv->per_device_auto_alloc_size; - if (size && !dev->uclass_priv) { - dev->uclass_priv = alloc_priv(size, - dev->uclass->uc_drv->flags); - if (!dev->uclass_priv) { - ret = -ENOMEM; - goto fail; - } - } - - /* Allocate parent data for this child */ - if (dev->parent) { - size = dev->parent->driver->per_child_auto_alloc_size; - if (!size) { - size = dev->parent->uclass->uc_drv-> - per_child_auto_alloc_size; - } - if (size && !dev->parent_priv) { - dev->parent_priv = alloc_priv(size, drv->flags); - if (!dev->parent_priv) { - ret = -ENOMEM; - goto fail; - } - } - } - - if (drv->ofdata_to_platdata && - (CONFIG_IS_ENABLED(OF_PLATDATA) || dev_has_of_node(dev))) { - ret = drv->ofdata_to_platdata(dev); + if (drv->of_to_plat && + (CONFIG_IS_ENABLED(OF_PLATDATA) || dev_has_ofnode(dev))) { + ret = drv->of_to_plat(dev); if (ret) goto fail; } - dev->flags |= DM_FLAG_PLATDATA_VALID; + dev_or_flags(dev, DM_FLAG_PLATDATA_VALID); return 0; fail: @@ -425,18 +425,17 @@ int device_probe(struct udevice *dev) { const struct driver *drv; int ret; - int seq; if (!dev) return -EINVAL; - if (dev->flags & DM_FLAG_ACTIVATED) + if (dev_get_flags(dev) & DM_FLAG_ACTIVATED) return 0; drv = dev->driver; assert(drv); - ret = device_ofdata_to_platdata(dev); + ret = device_of_to_plat(dev); if (ret) goto fail; @@ -452,18 +451,11 @@ int device_probe(struct udevice *dev) * (e.g. PCI bridge devices). Test the flags again * so that we don't mess up the device. */ - if (dev->flags & DM_FLAG_ACTIVATED) + if (dev_get_flags(dev) & DM_FLAG_ACTIVATED) return 0; } - seq = uclass_resolve_seq(dev); - if (seq < 0) { - ret = seq; - goto fail; - } - dev->seq = seq; - - dev->flags |= DM_FLAG_ACTIVATED; + dev_or_flags(dev, DM_FLAG_ACTIVATED); /* * Process pinctrl for everything except the root device, and @@ -493,7 +485,7 @@ int device_probe(struct udevice *dev) } /* Only handle devices that have a valid ofnode */ - if (dev_of_valid(dev)) { + if (dev_has_ofnode(dev)) { /* * Process 'assigned-{clocks/clock-parents/clock-rates}' * properties @@ -523,42 +515,41 @@ fail_uclass: __func__, dev->name); } fail: - dev->flags &= ~DM_FLAG_ACTIVATED; + dev_bic_flags(dev, DM_FLAG_ACTIVATED); - dev->seq = -1; device_free(dev); return ret; } -void *dev_get_platdata(const struct udevice *dev) +void *dev_get_plat(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); return NULL; } - return dev->platdata; + return dev->plat_; } -void *dev_get_parent_platdata(const struct udevice *dev) +void *dev_get_parent_plat(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); return NULL; } - return dev->parent_platdata; + return dev->parent_plat_; } -void *dev_get_uclass_platdata(const struct udevice *dev) +void *dev_get_uclass_plat(const struct udevice *dev) { if (!dev) { dm_warn("%s: null device\n", __func__); return NULL; } - return dev->uclass_platdata; + return dev->uclass_plat_; } void *dev_get_priv(const struct udevice *dev) @@ -568,7 +559,7 @@ void *dev_get_priv(const struct udevice *dev) return NULL; } - return dev->priv; + return dev->priv_; } void *dev_get_uclass_priv(const struct udevice *dev) @@ -578,7 +569,7 @@ void *dev_get_uclass_priv(const struct udevice *dev) return NULL; } - return dev->uclass_priv; + return dev->uclass_priv_; } void *dev_get_parent_priv(const struct udevice *dev) @@ -588,7 +579,7 @@ void *dev_get_parent_priv(const struct udevice *dev) return NULL; } - return dev->parent_priv; + return dev->parent_priv_; } static int device_get_device_tail(struct udevice *dev, int ret, @@ -622,7 +613,7 @@ static int device_find_by_ofnode(ofnode node, struct udevice **devp) struct udevice *dev; int ret; - list_for_each_entry(uc, &gd->uclass_root, sibling_node) { + list_for_each_entry(uc, gd->uclass_root, sibling_node) { ret = uclass_find_device_by_ofnode(uc->uc_drv->id, node, &dev); if (!ret || dev) { @@ -659,18 +650,15 @@ int device_get_child_count(const struct udevice *parent) return count; } -int device_find_child_by_seq(const struct udevice *parent, int seq_or_req_seq, - bool find_req_seq, struct udevice **devp) +int device_find_child_by_seq(const struct udevice *parent, int seq, + struct udevice **devp) { struct udevice *dev; *devp = NULL; - if (seq_or_req_seq == -1) - return -ENODEV; list_for_each_entry(dev, &parent->child_head, sibling_node) { - if ((find_req_seq ? dev->req_seq : dev->seq) == - seq_or_req_seq) { + if (dev->seq_ == seq) { *devp = dev; return 0; } @@ -686,14 +674,8 @@ int device_get_child_by_seq(const struct udevice *parent, int seq, int ret; *devp = NULL; - ret = device_find_child_by_seq(parent, seq, false, &dev); - if (ret == -ENODEV) { - /* - * We didn't find it in probed devices. See if there is one - * that will request this seq if probed. - */ - ret = device_find_child_by_seq(parent, seq, true, &dev); - } + ret = device_find_child_by_seq(parent, seq, &dev); + return device_get_device_tail(dev, ret, devp); } @@ -895,7 +877,7 @@ int device_first_child_ofdata_err(struct udevice *parent, struct udevice **devp) if (!dev) return -ENODEV; - ret = device_ofdata_to_platdata(dev); + ret = device_of_to_plat(dev); if (ret) return ret; @@ -913,7 +895,7 @@ int device_next_child_ofdata_err(struct udevice **devp) if (!dev) return -ENODEV; - ret = device_ofdata_to_platdata(dev); + ret = device_of_to_plat(dev); if (ret) return ret; @@ -983,7 +965,7 @@ bool device_is_last_sibling(const struct udevice *dev) void device_set_name_alloced(struct udevice *dev) { - dev->flags |= DM_FLAG_NAME_ALLOCED; + dev_or_flags(dev, DM_FLAG_NAME_ALLOCED); } int device_set_name(struct udevice *dev, const char *name) @@ -997,6 +979,36 @@ int device_set_name(struct udevice *dev, const char *name) return 0; } +void dev_set_priv(struct udevice *dev, void *priv) +{ + dev->priv_ = priv; +} + +void dev_set_parent_priv(struct udevice *dev, void *parent_priv) +{ + dev->parent_priv_ = parent_priv; +} + +void dev_set_uclass_priv(struct udevice *dev, void *uclass_priv) +{ + dev->uclass_priv_ = uclass_priv; +} + +void dev_set_plat(struct udevice *dev, void *plat) +{ + dev->plat_ = plat; +} + +void dev_set_parent_plat(struct udevice *dev, void *parent_plat) +{ + dev->parent_plat_ = parent_plat; +} + +void dev_set_uclass_plat(struct udevice *dev, void *uclass_plat) +{ + dev->uclass_plat_ = uclass_plat; +} + #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) bool device_is_compatible(const struct udevice *dev, const char *compat) { @@ -1020,7 +1032,7 @@ int dev_disable_by_path(const char *path) if (!of_live_active()) return -ENOSYS; - list_for_each_entry(uc, &gd->uclass_root, sibling_node) { + list_for_each_entry(uc, gd->uclass_root, sibling_node) { ret = uclass_find_device_by_ofnode(uc->uc_drv->id, node, &dev); if (!ret) break; diff --git a/drivers/core/devres.c b/drivers/core/devres.c index 88244698b0..313ddc7089 100644 --- a/drivers/core/devres.c +++ b/drivers/core/devres.c @@ -23,7 +23,7 @@ /** enum devres_phase - Shows where resource was allocated * * DEVRES_PHASE_BIND: In the bind() method - * DEVRES_PHASE_OFDATA: In the ofdata_to_platdata() method + * DEVRES_PHASE_OFDATA: In the of_to_plat() method * DEVRES_PHASE_PROBE: In the probe() method */ enum devres_phase { @@ -107,9 +107,9 @@ void devres_add(struct udevice *dev, void *res) devres_log(dev, dr, "ADD"); assert_noisy(list_empty(&dr->entry)); - if (dev->flags & DM_FLAG_PLATDATA_VALID) + if (dev_get_flags(dev) & DM_FLAG_PLATDATA_VALID) dr->phase = DEVRES_PHASE_PROBE; - else if (dev->flags & DM_FLAG_BOUND) + else if (dev_get_flags(dev) & DM_FLAG_BOUND) dr->phase = DEVRES_PHASE_OFDATA; else dr->phase = DEVRES_PHASE_BIND; diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 6debaf97a1..f8afea30a9 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -14,11 +14,13 @@ static void show_devices(struct udevice *dev, int depth, int last_flag) { int i, is_last; struct udevice *child; + u32 flags = dev_get_flags(dev); /* print the first 20 characters to not break the tree-format. */ - printf(" %-10.10s %3d [ %c ] %-20.20s ", dev->uclass->uc_drv->name, + printf(IS_ENABLED(CONFIG_SPL_BUILD) ? " %s %d [ %c ] %s " : + " %-10.10s %3d [ %c ] %-20.20s ", dev->uclass->uc_drv->name, dev_get_uclass_index(dev, NULL), - dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name); + flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name); for (i = depth; i >= 0; i--) { is_last = (last_flag >> i) & 1; @@ -65,10 +67,10 @@ void dm_dump_all(void) static void dm_display_line(struct udevice *dev, int index) { printf("%-3i %c %s @ %08lx", index, - dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ', + dev_get_flags(dev) & DM_FLAG_ACTIVATED ? '*' : ' ', dev->name, (ulong)map_to_sysmem(dev)); - if (dev->seq != -1 || dev->req_seq != -1) - printf(", seq %d, (req %d)", dev->seq, dev->req_seq); + if (dev->seq_ != -1) + printf(", seq %d", dev_seq(dev)); puts("\n"); } @@ -170,6 +172,6 @@ void dm_dump_static_driver_info(void) puts("---------------------------------\n"); for (entry = drv; entry != drv + n_ents; entry++) { printf("%-25.25s @%08lx\n", entry->name, - (ulong)map_to_sysmem(entry->platdata)); + (ulong)map_to_sysmem(entry->plat)); } } diff --git a/drivers/core/lists.c b/drivers/core/lists.c index b23ee3030e..e214306b90 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -39,8 +39,8 @@ struct driver *lists_driver_lookup_name(const char *name) struct uclass_driver *lists_uclass_lookup(enum uclass_id id) { struct uclass_driver *uclass = - ll_entry_start(struct uclass_driver, uclass); - const int n_ents = ll_entry_count(struct uclass_driver, uclass); + ll_entry_start(struct uclass_driver, uclass_driver); + const int n_ents = ll_entry_count(struct uclass_driver, uclass_driver); struct uclass_driver *entry; for (entry = uclass; entry != uclass + n_ents; entry++) { @@ -251,7 +251,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, if (ret) { dm_warn("Error binding driver '%s': %d\n", entry->name, ret); - return ret; + return log_msg_ret("bind", ret); } else { found = true; if (devp) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index a68076bf35..2a6e43ddc6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -226,6 +226,17 @@ int ofnode_read_u32_array(ofnode node, const char *propname, } } +#if !CONFIG_IS_ENABLED(DM_INLINE_OFNODE) +bool ofnode_is_enabled(ofnode node) +{ + if (ofnode_is_np(node)) { + return of_device_is_available(ofnode_to_np(node)); + } else { + return fdtdec_get_is_enabled(gd->fdt_blob, + ofnode_to_offset(node)); + } +} + ofnode ofnode_first_subnode(ofnode node) { assert(ofnode_valid(node)); @@ -245,6 +256,7 @@ ofnode ofnode_next_subnode(ofnode node) return offset_to_ofnode( fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node))); } +#endif /* !DM_INLINE_OFNODE */ ofnode ofnode_get_parent(ofnode node) { diff --git a/drivers/core/read.c b/drivers/core/read.c index 076125824c..fc74d64814 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -281,8 +281,10 @@ int dev_read_alias_seq(const struct udevice *dev, int *devnump) if (ofnode_is_np(node)) { ret = of_alias_get_id(ofnode_to_np(node), uc_name); - if (ret >= 0) + if (ret >= 0) { *devnump = ret; + ret = 0; + } } else { #if CONFIG_IS_ENABLED(OF_CONTROL) ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name, diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index c2bed88eac..4baacabd01 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -60,8 +60,8 @@ static struct regmap *regmap_alloc(int count) } #if CONFIG_IS_ENABLED(OF_PLATDATA) -int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count, - struct regmap **mapp) +int regmap_init_mem_plat(struct udevice *dev, fdt_val_t *reg, int count, + struct regmap **mapp) { struct regmap_range *range; struct regmap *map; diff --git a/drivers/core/root.c b/drivers/core/root.c index 5f10d7a39c..78de7cdf87 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -45,8 +45,8 @@ void dm_fixup_for_gd_move(struct global_data *new_gd) { /* The sentinel node has moved, so update things that point to it */ if (gd->dm_root) { - new_gd->uclass_root.next->prev = &new_gd->uclass_root; - new_gd->uclass_root.prev->next = &new_gd->uclass_root; + new_gd->uclass_root->next->prev = new_gd->uclass_root; + new_gd->uclass_root->prev->next = new_gd->uclass_root; } } @@ -69,8 +69,8 @@ void fix_drivers(void) entry->remove += gd->reloc_off; if (entry->unbind) entry->unbind += gd->reloc_off; - if (entry->ofdata_to_platdata) - entry->ofdata_to_platdata += gd->reloc_off; + if (entry->of_to_plat) + entry->of_to_plat += gd->reloc_off; if (entry->child_post_bind) entry->child_post_bind += gd->reloc_off; if (entry->child_pre_probe) @@ -86,8 +86,8 @@ void fix_drivers(void) void fix_uclass(void) { struct uclass_driver *uclass = - ll_entry_start(struct uclass_driver, uclass); - const int n_ents = ll_entry_count(struct uclass_driver, uclass); + ll_entry_start(struct uclass_driver, uclass_driver); + const int n_ents = ll_entry_count(struct uclass_driver, uclass_driver); struct uclass_driver *entry; for (entry = uclass; entry != uclass + n_ents; entry++) { @@ -123,8 +123,8 @@ void fix_devices(void) struct driver_info *entry; for (entry = dev; entry != dev + n_ents; entry++) { - if (entry->platdata) - entry->platdata += gd->reloc_off; + if (entry->plat) + entry->plat += gd->reloc_off; } } @@ -136,7 +136,8 @@ int dm_init(bool of_live) dm_warn("Virtual root driver already exists!\n"); return -EINVAL; } - INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST); + gd->uclass_root = &DM_UCLASS_ROOT_S_NON_CONST; + INIT_LIST_HEAD(DM_UCLASS_ROOT_NON_CONST); if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) { fix_drivers(); @@ -147,12 +148,8 @@ int dm_init(bool of_live) ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST); if (ret) return ret; -#if CONFIG_IS_ENABLED(OF_CONTROL) - if (CONFIG_IS_ENABLED(OF_LIVE) && of_live) - DM_ROOT_NON_CONST->node = np_to_ofnode(gd_of_root()); - else - DM_ROOT_NON_CONST->node = offset_to_ofnode(0); -#endif + if (CONFIG_IS_ENABLED(OF_CONTROL)) + dev_set_ofnode(DM_ROOT_NON_CONST, ofnode_root()); ret = device_probe(DM_ROOT_NON_CONST); if (ret) return ret; @@ -178,7 +175,7 @@ int dm_remove_devices_flags(uint flags) } #endif -int dm_scan_platdata(bool pre_reloc_only) +int dm_scan_plat(bool pre_reloc_only) { int ret; @@ -203,33 +200,6 @@ int dm_scan_platdata(bool pre_reloc_only) } #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) -static int dm_scan_fdt_live(struct udevice *parent, - const struct device_node *node_parent, - bool pre_reloc_only) -{ - struct device_node *np; - int ret = 0, err; - - for (np = node_parent->child; np; np = np->sibling) { - - if (!of_device_is_available(np)) { - pr_debug(" - ignoring disabled device\n"); - continue; - } - err = lists_bind_fdt(parent, np_to_ofnode(np), NULL, - pre_reloc_only); - if (err && !ret) { - ret = err; - debug("%s: ret=%d\n", np->name, ret); - } - } - - if (ret) - dm_warn("Some drivers failed to bind\n"); - - return ret; -} - /** * dm_scan_fdt_node() - Scan the device tree and bind drivers for a node * @@ -237,28 +207,30 @@ static int dm_scan_fdt_live(struct udevice *parent, * for each one. * * @parent: Parent device for the devices that will be created - * @blob: Pointer to device tree blob - * @offset: Offset of node to scan + * @node: Node to scan * @pre_reloc_only: If true, bind only drivers with the DM_FLAG_PRE_RELOC * flag. If false bind all drivers. * @return 0 if OK, -ve on error */ -static int dm_scan_fdt_node(struct udevice *parent, const void *blob, - int offset, bool pre_reloc_only) +static int dm_scan_fdt_node(struct udevice *parent, ofnode parent_node, + bool pre_reloc_only) { int ret = 0, err; + ofnode node; - for (offset = fdt_first_subnode(blob, offset); - offset > 0; - offset = fdt_next_subnode(blob, offset)) { - const char *node_name = fdt_get_name(blob, offset, NULL); + if (!ofnode_valid(parent_node)) + return 0; + + for (node = ofnode_first_subnode(parent_node); + ofnode_valid(node); + node = ofnode_next_subnode(node)) { + const char *node_name = ofnode_get_name(node); - if (!fdtdec_get_is_enabled(blob, offset)) { + if (!ofnode_is_enabled(node)) { pr_debug(" - ignoring disabled device\n"); continue; } - err = lists_bind_fdt(parent, offset_to_ofnode(offset), NULL, - pre_reloc_only); + err = lists_bind_fdt(parent, node, NULL, pre_reloc_only); if (err && !ret) { ret = err; debug("%s: ret=%d\n", node_name, ret); @@ -273,43 +245,25 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, int dm_scan_fdt_dev(struct udevice *dev) { - if (!dev_of_valid(dev)) - return 0; - - if (of_live_active()) - return dm_scan_fdt_live(dev, dev_np(dev), - gd->flags & GD_FLG_RELOC ? false : true); - - return dm_scan_fdt_node(dev, gd->fdt_blob, dev_of_offset(dev), + return dm_scan_fdt_node(dev, dev_ofnode(dev), gd->flags & GD_FLG_RELOC ? false : true); } -int dm_scan_fdt(const void *blob, bool pre_reloc_only) +int dm_scan_fdt(bool pre_reloc_only) { - if (of_live_active()) - return dm_scan_fdt_live(gd->dm_root, gd_of_root(), - pre_reloc_only); - - return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); + return dm_scan_fdt_node(gd->dm_root, ofnode_root(), pre_reloc_only); } -static int dm_scan_fdt_ofnode_path(const void *blob, const char *path, - bool pre_reloc_only) +static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) { ofnode node; node = ofnode_path(path); - if (!ofnode_valid(node)) - return 0; - - if (of_live_active()) - return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only); - return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset, - pre_reloc_only); + return dm_scan_fdt_node(gd->dm_root, node, pre_reloc_only); } -int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) +int dm_extended_scan(bool pre_reloc_only) { int ret, i; const char * const nodes[] = { @@ -318,7 +272,7 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) "/firmware" }; - ret = dm_scan_fdt(blob, pre_reloc_only); + ret = dm_scan_fdt(pre_reloc_only); if (ret) { debug("dm_scan_fdt() failed: %d\n", ret); return ret; @@ -326,7 +280,7 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) /* Some nodes aren't devices themselves but may contain some */ for (i = 0; i < ARRAY_SIZE(nodes); i++) { - ret = dm_scan_fdt_ofnode_path(blob, nodes[i], pre_reloc_only); + ret = dm_scan_fdt_ofnode_path(nodes[i], pre_reloc_only); if (ret) { debug("dm_scan_fdt() scan for %s failed: %d\n", nodes[i], ret); @@ -343,28 +297,30 @@ __weak int dm_scan_other(bool pre_reloc_only) return 0; } -int dm_init_and_scan(bool pre_reloc_only) +/** + * dm_scan() - Scan tables to bind devices + * + * Runs through the driver_info tables and binds the devices it finds. Then runs + * through the devicetree nodes. Finally calls dm_scan_other() to add any + * special devices + * + * @pre_reloc_only: If true, bind only nodes with special devicetree properties, + * or drivers with the DM_FLAG_PRE_RELOC flag. If false bind all drivers. + */ +static int dm_scan(bool pre_reloc_only) { int ret; - if (CONFIG_IS_ENABLED(OF_PLATDATA)) - dm_populate_phandle_data(); - - ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE)); + ret = dm_scan_plat(pre_reloc_only); if (ret) { - debug("dm_init() failed: %d\n", ret); - return ret; - } - ret = dm_scan_platdata(pre_reloc_only); - if (ret) { - debug("dm_scan_platdata() failed: %d\n", ret); + debug("dm_scan_plat() failed: %d\n", ret); return ret; } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { - ret = dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only); + ret = dm_extended_scan(pre_reloc_only); if (ret) { - debug("dm_extended_scan_dt() failed: %d\n", ret); + debug("dm_extended_scan() failed: %d\n", ret); return ret; } } @@ -376,6 +332,24 @@ int dm_init_and_scan(bool pre_reloc_only) return 0; } +int dm_init_and_scan(bool pre_reloc_only) +{ + int ret; + + ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE)); + if (ret) { + debug("dm_init() failed: %d\n", ret); + return ret; + } + ret = dm_scan(pre_reloc_only); + if (ret) { + log_debug("dm_scan() failed: %d\n", ret); + return ret; + } + + return 0; +} + #ifdef CONFIG_ACPIGEN static int root_acpi_get_name(const struct udevice *dev, char *out_name) { diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c index 7cc1d46009..b0c2c20958 100644 --- a/drivers/core/simple-bus.c +++ b/drivers/core/simple-bus.c @@ -5,16 +5,11 @@ #include <common.h> #include <dm.h> - -struct simple_bus_plat { - u32 base; - u32 size; - u32 target; -}; +#include <dm/simple_bus.h> fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr) { - struct simple_bus_plat *plat = dev_get_uclass_platdata(dev); + struct simple_bus_plat *plat = dev_get_uclass_plat(dev); if (addr >= plat->base && addr < plat->base + plat->size) addr = (addr - plat->base) + plat->target; @@ -32,7 +27,7 @@ static int simple_bus_post_bind(struct udevice *dev) ret = dev_read_u32_array(dev, "ranges", cell, ARRAY_SIZE(cell)); if (!ret) { - struct simple_bus_plat *plat = dev_get_uclass_platdata(dev); + struct simple_bus_plat *plat = dev_get_uclass_plat(dev); plat->base = cell[0]; plat->target = cell[1]; @@ -47,18 +42,20 @@ UCLASS_DRIVER(simple_bus) = { .id = UCLASS_SIMPLE_BUS, .name = "simple_bus", .post_bind = simple_bus_post_bind, - .per_device_platdata_auto_alloc_size = sizeof(struct simple_bus_plat), + .per_device_plat_auto = sizeof(struct simple_bus_plat), }; +#if !CONFIG_IS_ENABLED(OF_PLATDATA) static const struct udevice_id generic_simple_bus_ids[] = { { .compatible = "simple-bus" }, { .compatible = "simple-mfd" }, { } }; +#endif U_BOOT_DRIVER(simple_bus) = { .name = "simple_bus", .id = UCLASS_SIMPLE_BUS, - .of_match = generic_simple_bus_ids, + .of_match = of_match_ptr(generic_simple_bus_ids), .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/core/simple-pm-bus.c b/drivers/core/simple-pm-bus.c index 51dc9b206f..7a18953cba 100644 --- a/drivers/core/simple-pm-bus.c +++ b/drivers/core/simple-pm-bus.c @@ -51,6 +51,6 @@ U_BOOT_DRIVER(simple_pm_bus_drv) = { .of_match = simple_pm_bus_ids, .probe = simple_pm_bus_probe, .remove = simple_pm_bus_remove, - .priv_auto_alloc_size = sizeof(struct clk_bulk), + .priv_auto = sizeof(struct clk_bulk), .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 567d0a4b50..cb33facc71 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -56,9 +56,9 @@ static int syscon_pre_probe(struct udevice *dev) * using OF_PLATDATA will need to ensure that this is true. */ #if CONFIG_IS_ENABLED(OF_PLATDATA) - struct syscon_base_platdata *plat = dev_get_platdata(dev); + struct syscon_base_plat *plat = dev_get_plat(dev); - return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg), + return regmap_init_mem_plat(dev, plat->reg, ARRAY_SIZE(plat->reg), &priv->regmap); #else return regmap_init_mem(dev_ofnode(dev), &priv->regmap); @@ -174,7 +174,7 @@ void *syscon_get_first_range(ulong driver_data) UCLASS_DRIVER(syscon) = { .id = UCLASS_SYSCON, .name = "syscon", - .per_device_auto_alloc_size = sizeof(struct syscon_uc_info), + .per_device_auto = sizeof(struct syscon_uc_info), .pre_probe = syscon_pre_probe, }; diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index c3f1b73cd6..cdb975d5b3 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -33,7 +33,7 @@ struct uclass *uclass_find(enum uclass_id key) * node to the start of the list, or creating a linear array mapping * id to node. */ - list_for_each_entry(uc, &gd->uclass_root, sibling_node) { + list_for_each_entry(uc, gd->uclass_root, sibling_node) { if (uc->uc_drv->id == key) return uc; } @@ -71,17 +71,20 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp) uc = calloc(1, sizeof(*uc)); if (!uc) return -ENOMEM; - if (uc_drv->priv_auto_alloc_size) { - uc->priv = calloc(1, uc_drv->priv_auto_alloc_size); - if (!uc->priv) { + if (uc_drv->priv_auto) { + void *ptr; + + ptr = calloc(1, uc_drv->priv_auto); + if (!ptr) { ret = -ENOMEM; goto fail_mem; } + uclass_set_priv(uc, ptr); } uc->uc_drv = uc_drv; INIT_LIST_HEAD(&uc->sibling_node); INIT_LIST_HEAD(&uc->dev_head); - list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST); + list_add(&uc->sibling_node, DM_UCLASS_ROOT_NON_CONST); if (uc_drv->init) { ret = uc_drv->init(uc); @@ -93,9 +96,9 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp) return 0; fail: - if (uc_drv->priv_auto_alloc_size) { - free(uc->priv); - uc->priv = NULL; + if (uc_drv->priv_auto) { + free(uclass_get_priv(uc)); + uclass_set_priv(uc, NULL); } list_del(&uc->sibling_node); fail_mem: @@ -131,8 +134,8 @@ int uclass_destroy(struct uclass *uc) if (uc_drv->destroy) uc_drv->destroy(uc); list_del(&uc->sibling_node); - if (uc_drv->priv_auto_alloc_size) - free(uc->priv); + if (uc_drv->priv_auto) + free(uclass_get_priv(uc)); free(uc); return 0; @@ -160,6 +163,16 @@ const char *uclass_get_name(enum uclass_id id) return uc->uc_drv->name; } +void *uclass_get_priv(const struct uclass *uc) +{ + return uc->priv_; +} + +void uclass_set_priv(struct uclass *uc, void *priv) +{ + uc->priv_ = priv; +} + enum uclass_id uclass_get_by_name(const char *name) { int i; @@ -272,48 +285,46 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name, return -ENODEV; } -int uclass_find_next_free_req_seq(enum uclass_id id) +int uclass_find_next_free_seq(struct uclass *uc) { - struct uclass *uc; struct udevice *dev; - int ret; int max = -1; - ret = uclass_get(id, &uc); - if (ret) - return ret; + /* If using aliases, start with the highest alias value */ + if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) && + (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) + max = dev_read_alias_highest_id(uc->uc_drv->name); + /* Avoid conflict with existing devices */ list_for_each_entry(dev, &uc->dev_head, uclass_node) { - if ((dev->req_seq != -1) && (dev->req_seq > max)) - max = dev->req_seq; + if (dev->seq_ > max) + max = dev->seq_; } - - if (max == -1) - return 0; + /* + * At this point, max will be -1 if there are no existing aliases or + * devices + */ return max + 1; } -int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, - bool find_req_seq, struct udevice **devp) +int uclass_find_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) { struct uclass *uc; struct udevice *dev; int ret; *devp = NULL; - log_debug("%d %d\n", find_req_seq, seq_or_req_seq); - if (seq_or_req_seq == -1) + log_debug("%d\n", seq); + if (seq == -1) return -ENODEV; ret = uclass_get(id, &uc); if (ret) return ret; uclass_foreach_dev(dev, uc) { - log_debug(" - %d %d '%s'\n", - dev->req_seq, dev->seq, dev->name); - if ((find_req_seq ? dev->req_seq : dev->seq) == - seq_or_req_seq) { + log_debug(" - %d '%s'\n", dev->seq_, dev->name); + if (dev->seq_ == seq) { *devp = dev; log_debug(" - found\n"); return 0; @@ -473,14 +484,8 @@ int uclass_get_device_by_seq(enum uclass_id id, int seq, struct udevice **devp) int ret; *devp = NULL; - ret = uclass_find_device_by_seq(id, seq, false, &dev); - if (ret == -ENODEV) { - /* - * We didn't find it in probed devices. See if there is one - * that will request this seq if probed. - */ - ret = uclass_find_device_by_seq(id, seq, true, &dev); - } + ret = uclass_find_device_by_seq(id, seq, &dev); + return uclass_get_device_tail(dev, ret, devp); } @@ -687,46 +692,6 @@ int uclass_unbind_device(struct udevice *dev) } #endif -int uclass_resolve_seq(struct udevice *dev) -{ - struct uclass *uc = dev->uclass; - struct uclass_driver *uc_drv = uc->uc_drv; - struct udevice *dup; - int seq = 0; - int ret; - - assert(dev->seq == -1); - ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup); - if (!ret) { - dm_warn("Device '%s': seq %d is in use by '%s'\n", - dev->name, dev->req_seq, dup->name); - } else if (ret == -ENODEV) { - /* Our requested sequence number is available */ - if (dev->req_seq != -1) - return dev->req_seq; - } else { - return ret; - } - - if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS) && - (uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) { - /* - * dev_read_alias_highest_id() will return -1 if there no - * alias. Thus we can always add one. - */ - seq = dev_read_alias_highest_id(uc_drv->name) + 1; - } - - for (; seq < DM_MAX_SEQ; seq++) { - ret = uclass_find_device_by_seq(uc_drv->id, seq, false, &dup); - if (ret == -ENODEV) - break; - if (ret) - return ret; - } - return seq; -} - int uclass_pre_probe_device(struct udevice *dev) { struct uclass_driver *uc_drv; |