diff options
Diffstat (limited to 'drivers/core')
-rw-r--r-- | drivers/core/Kconfig | 16 | ||||
-rw-r--r-- | drivers/core/device-remove.c | 1 | ||||
-rw-r--r-- | drivers/core/device.c | 50 | ||||
-rw-r--r-- | drivers/core/dump.c | 4 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 2 | ||||
-rw-r--r-- | drivers/core/read.c | 4 | ||||
-rw-r--r-- | drivers/core/root.c | 8 | ||||
-rw-r--r-- | drivers/core/uclass.c | 86 |
8 files changed, 60 insertions, 111 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/device-remove.c b/drivers/core/device-remove.c index 9f7615dea7..289220b98e 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -207,7 +207,6 @@ 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; } diff --git a/drivers/core/device.c b/drivers/core/device.c index a6b8c3ef24..d1a08ce783 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -41,6 +41,7 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, struct udevice *dev; struct uclass *uc; int size, ret = 0; + bool auto_seq = true; if (devp) *devp = NULL; @@ -71,30 +72,23 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, dev->driver = drv; dev->uclass = uc; - dev->seq = -1; - dev->req_seq = -1; + dev->sqq = -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->sqq)) + auto_seq = false; + } } } + if (auto_seq && !(uc->uc_drv->flags & DM_UC_FLAG_NO_AUTO_SEQ)) + dev->sqq = uclass_find_next_free_seq(uc); if (drv->plat_auto) { bool alloc = !plat; @@ -411,7 +405,6 @@ int device_probe(struct udevice *dev) { const struct driver *drv; int ret; - int seq; if (!dev) return -EINVAL; @@ -442,13 +435,6 @@ int device_probe(struct udevice *dev) return 0; } - seq = uclass_resolve_seq(dev); - if (seq < 0) { - ret = seq; - goto fail; - } - dev->seq = seq; - dev->flags |= DM_FLAG_ACTIVATED; /* @@ -511,7 +497,6 @@ fail_uclass: fail: dev->flags &= ~DM_FLAG_ACTIVATED; - dev->seq = -1; device_free(dev); return ret; @@ -645,18 +630,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->sqq == seq) { *devp = dev; return 0; } @@ -672,14 +654,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); } diff --git a/drivers/core/dump.c b/drivers/core/dump.c index 221b4f79f2..2012547321 100644 --- a/drivers/core/dump.c +++ b/drivers/core/dump.c @@ -67,8 +67,8 @@ static void dm_display_line(struct udevice *dev, int index) printf("%-3i %c %s @ %08lx", index, dev->flags & 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->sqq != -1) + printf(", seq %d", dev_seq(dev)); puts("\n"); } diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 87072094f3..2a6e43ddc6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -226,6 +226,7 @@ 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)) { @@ -255,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/root.c b/drivers/core/root.c index 672aa7cea7..f2fba5883a 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -311,22 +311,24 @@ int dm_init_and_scan(bool pre_reloc_only) ret = dm_scan_plat(pre_reloc_only); if (ret) { debug("dm_scan_plat() failed: %d\n", ret); - return ret; + goto fail; } if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = dm_extended_scan(pre_reloc_only); if (ret) { debug("dm_extended_scan() failed: %d\n", ret); - return ret; + goto fail; } } ret = dm_scan_other(pre_reloc_only); if (ret) - return ret; + goto fail; return 0; +fail: + return ret; } #ifdef CONFIG_ACPIGEN diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index b1d882e14e..6409457fa9 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -272,48 +272,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->sqq > max) + max = dev->sqq; } - - 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->sqq, dev->name); + if (dev->sqq == seq) { *devp = dev; log_debug(" - found\n"); return 0; @@ -473,14 +471,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 +679,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; |