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/acpi.c2
-rw-r--r--drivers/core/device-remove.c51
-rw-r--r--drivers/core/device.c320
-rw-r--r--drivers/core/devres.c6
-rw-r--r--drivers/core/dump.c14
-rw-r--r--drivers/core/lists.c6
-rw-r--r--drivers/core/ofnode.c12
-rw-r--r--drivers/core/read.c4
-rw-r--r--drivers/core/regmap.c4
-rw-r--r--drivers/core/root.c160
-rw-r--r--drivers/core/simple-bus.c17
-rw-r--r--drivers/core/simple-pm-bus.c2
-rw-r--r--drivers/core/syscon-uclass.c6
-rw-r--r--drivers/core/uclass.c119
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;