aboutsummaryrefslogtreecommitdiff
path: root/drivers/core/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/core/root.c')
-rw-r--r--drivers/core/root.c160
1 files changed, 67 insertions, 93 deletions
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)
{