aboutsummaryrefslogtreecommitdiff
path: root/drivers/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core')
-rw-r--r--drivers/core/Kconfig16
-rw-r--r--drivers/core/device-remove.c1
-rw-r--r--drivers/core/device.c50
-rw-r--r--drivers/core/dump.c4
-rw-r--r--drivers/core/ofnode.c2
-rw-r--r--drivers/core/read.c4
-rw-r--r--drivers/core/root.c8
-rw-r--r--drivers/core/uclass.c86
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;