diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/altera/clk-arria10.c | 2 | ||||
-rw-r--r-- | drivers/clk/at91/pmc.c | 2 | ||||
-rw-r--r-- | drivers/core/device-remove.c | 23 | ||||
-rw-r--r-- | drivers/core/device.c | 22 | ||||
-rw-r--r-- | drivers/core/lists.c | 2 | ||||
-rw-r--r-- | drivers/core/of_access.c | 40 | ||||
-rw-r--r-- | drivers/core/ofnode.c | 49 | ||||
-rw-r--r-- | drivers/core/read.c | 13 | ||||
-rw-r--r-- | drivers/core/root.c | 52 | ||||
-rw-r--r-- | drivers/core/uclass.c | 6 | ||||
-rw-r--r-- | drivers/core/util.c | 28 | ||||
-rw-r--r-- | drivers/misc/p2sb_emul.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial-uclass.c | 1 |
13 files changed, 129 insertions, 113 deletions
diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c index b7eed948a5..694a9427e1 100644 --- a/drivers/clk/altera/clk-arria10.c +++ b/drivers/clk/altera/clk-arria10.c @@ -258,7 +258,7 @@ static int socfpga_a10_clk_bind(struct udevice *dev) continue; if (pre_reloc_only && - !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) + !ofnode_pre_reloc(offset_to_ofnode(offset))) continue; ret = device_bind_driver_to_node(dev, "clk-a10", name, diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 6b55ec59d6..f5808449a6 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -61,7 +61,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name) offset > 0; offset = fdt_next_subnode(fdt, offset)) { if (pre_reloc_only && - !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) + !ofnode_pre_reloc(offset_to_ofnode(offset))) continue; /* * If this node has "compatible" property, this is not diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index ff5b28cb6a..efdb0f2905 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -10,6 +10,7 @@ #include <common.h> #include <errno.h> +#include <log.h> #include <malloc.h> #include <dm/device.h> #include <dm/device-internal.h> @@ -30,11 +31,14 @@ int device_chld_unbind(struct udevice *dev, struct driver *drv) continue; ret = device_unbind(pos); - if (ret && !saved_ret) + if (ret && !saved_ret) { + log_warning("device '%s' failed to unbind\n", + pos->name); saved_ret = ret; + } } - return saved_ret; + return log_ret(saved_ret); } int device_chld_remove(struct udevice *dev, struct driver *drv, @@ -63,13 +67,13 @@ int device_unbind(struct udevice *dev) int ret; if (!dev) - return -EINVAL; + return log_msg_ret("dev", -EINVAL); if (dev->flags & DM_FLAG_ACTIVATED) - return -EINVAL; + return log_msg_ret("active", -EINVAL); if (!(dev->flags & DM_FLAG_BOUND)) - return -EINVAL; + return log_msg_ret("not-bound", -EINVAL); drv = dev->driver; assert(drv); @@ -77,12 +81,12 @@ int device_unbind(struct udevice *dev) if (drv->unbind) { ret = drv->unbind(dev); if (ret) - return ret; + return log_msg_ret("unbind", ret); } ret = device_chld_unbind(dev, NULL); if (ret) - return ret; + return log_msg_ret("child unbind", ret); if (dev->flags & DM_FLAG_ALLOC_PDATA) { free(dev->platdata); @@ -98,7 +102,7 @@ int device_unbind(struct udevice *dev) } ret = uclass_unbind_device(dev); if (ret) - return ret; + return log_msg_ret("uc", ret); if (dev->parent) list_del(&dev->sibling_node); @@ -194,7 +198,8 @@ int device_remove(struct udevice *dev, uint flags) } } - if (!(drv->flags & + if (!(flags & DM_REMOVE_NO_PD) && + !(drv->flags & (DM_FLAG_DEFAULT_PD_CTRL_OFF | DM_FLAG_REMOVE_WITH_PD_ON)) && dev != gd->cur_serial_dev) dev_power_domain_off(dev); diff --git a/drivers/core/device.c b/drivers/core/device.c index 89ea820d48..0157bb1fe0 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -143,11 +143,9 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv, goto fail_alloc3; } } - } - - /* put dev into parent's successor list */ - if (parent) + /* put dev into parent's successor list */ list_add_tail(&dev->sibling_node, &parent->child_head); + } ret = uclass_bind_device(dev); if (ret) @@ -323,6 +321,22 @@ int device_ofdata_to_platdata(struct udevice *dev) if (dev->flags & DM_FLAG_PLATDATA_VALID) return 0; + /* Ensure all parents have ofdata */ + if (dev->parent) { + ret = device_ofdata_to_platdata(dev->parent); + if (ret) + goto fail; + + /* + * The device might have already been probed during + * the call to device_probe() on its parent device + * (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) + return 0; + } + drv = dev->driver; assert(drv); diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 68204c303f..c7db14ed56 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -175,7 +175,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, continue; if (pre_reloc_only) { - if (!dm_ofnode_pre_reloc(node) && + if (!ofnode_pre_reloc(node) && !(entry->flags & DM_FLAG_PRE_RELOC)) { log_debug("Skipping device pre-relocation\n"); return 0; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index acd745c121..c54baa140a 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -449,21 +449,7 @@ static void *of_find_property_value_of_size(const struct device_node *np, int of_read_u32(const struct device_node *np, const char *propname, u32 *outp) { - const __be32 *val; - - debug("%s: %s: ", __func__, propname); - if (!np) - return -EINVAL; - val = of_find_property_value_of_size(np, propname, sizeof(*outp)); - if (IS_ERR(val)) { - debug("(not found)\n"); - return PTR_ERR(val); - } - - *outp = be32_to_cpup(val); - debug("%#x (%d)\n", *outp, *outp); - - return 0; + return of_read_u32_index(np, propname, 0, outp); } int of_read_u32_array(const struct device_node *np, const char *propname, @@ -485,6 +471,28 @@ int of_read_u32_array(const struct device_node *np, const char *propname, return 0; } +int of_read_u32_index(const struct device_node *np, const char *propname, + int index, u32 *outp) +{ + const __be32 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + + val = of_find_property_value_of_size(np, propname, + sizeof(*outp) * (index + 1)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = be32_to_cpup(val + index); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + int of_read_u64(const struct device_node *np, const char *propname, u64 *outp) { const __be64 *val; @@ -577,7 +585,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, { const __be32 *list, *list_end; int rc = 0, cur_index = 0; - uint32_t count = 0; + uint32_t count; struct device_node *node = NULL; phandle phandle; int size; diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 96a5dd20bd..b0be7cbe19 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -18,32 +18,53 @@ int ofnode_read_u32(ofnode node, const char *propname, u32 *outp) { + return ofnode_read_u32_index(node, propname, 0, outp); +} + +u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u32_index(node, propname, 0, &def); + + return def; +} + +int ofnode_read_u32_index(ofnode node, const char *propname, int index, + u32 *outp) +{ + const fdt32_t *cell; + int len; + assert(ofnode_valid(node)); debug("%s: %s: ", __func__, propname); - if (ofnode_is_np(node)) { - return of_read_u32(ofnode_to_np(node), propname, outp); - } else { - const fdt32_t *cell; - int len; + if (ofnode_is_np(node)) + return of_read_u32_index(ofnode_to_np(node), propname, index, + outp); - cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), - propname, &len); - if (!cell || len < sizeof(int)) { - debug("(not found)\n"); - return -EINVAL; - } - *outp = fdt32_to_cpu(cell[0]); + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell) { + debug("(not found)\n"); + return -EINVAL; + } + + if (len < (sizeof(int) * (index + 1))) { + debug("(not large enough)\n"); + return -EOVERFLOW; } + + *outp = fdt32_to_cpu(cell[index]); debug("%#x (%d)\n", *outp, *outp); return 0; } -u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def) +u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index, + u32 def) { assert(ofnode_valid(node)); - ofnode_read_u32(node, propname, &def); + ofnode_read_u32_index(node, propname, index, &def); return def; } diff --git a/drivers/core/read.c b/drivers/core/read.c index 1f999b1b31..ce78f09d28 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -22,6 +22,19 @@ int dev_read_u32_default(const struct udevice *dev, const char *propname, return ofnode_read_u32_default(dev_ofnode(dev), propname, def); } +int dev_read_u32_index(struct udevice *dev, const char *propname, int index, + u32 *outp) +{ + return ofnode_read_u32_index(dev_ofnode(dev), propname, index, outp); +} + +u32 dev_read_u32_index_default(struct udevice *dev, const char *propname, + int index, u32 def) +{ + return ofnode_read_u32_index_default(dev_ofnode(dev), propname, index, + def); +} + int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp) { return ofnode_read_u32(dev_ofnode(dev), propname, (u32 *)outp); diff --git a/drivers/core/root.c b/drivers/core/root.c index e85643819e..14df16c280 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -203,15 +203,6 @@ static int dm_scan_fdt_live(struct udevice *parent, int ret = 0, err; for (np = node_parent->child; np; np = np->sibling) { - /* "chosen" node isn't a device itself but may contain some: */ - if (!strcmp(np->name, "chosen")) { - pr_debug("parsing subnodes of \"chosen\"\n"); - - err = dm_scan_fdt_live(parent, np, pre_reloc_only); - if (err && !ret) - ret = err; - continue; - } if (!of_device_is_available(np)) { pr_debug(" - ignoring disabled device\n"); @@ -256,21 +247,6 @@ static int dm_scan_fdt_node(struct udevice *parent, const void *blob, offset = fdt_next_subnode(blob, offset)) { const char *node_name = fdt_get_name(blob, offset, NULL); - /* - * The "chosen" and "firmware" nodes aren't devices - * themselves but may contain some: - */ - if (!strcmp(node_name, "chosen") || - !strcmp(node_name, "firmware")) { - pr_debug("parsing subnodes of \"%s\"\n", node_name); - - err = dm_scan_fdt_node(parent, blob, offset, - pre_reloc_only); - if (err && !ret) - ret = err; - continue; - } - if (!fdtdec_get_is_enabled(blob, offset)) { pr_debug(" - ignoring disabled device\n"); continue; @@ -315,7 +291,8 @@ int dm_scan_fdt(const void *blob, bool pre_reloc_only) return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); } -static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) +static int dm_scan_fdt_ofnode_path(const void *blob, const char *path, + bool pre_reloc_only) { ofnode node; @@ -327,13 +304,18 @@ static int dm_scan_fdt_ofnode_path(const char *path, bool pre_reloc_only) if (of_live_active()) return dm_scan_fdt_live(gd->dm_root, node.np, pre_reloc_only); #endif - return dm_scan_fdt_node(gd->dm_root, gd->fdt_blob, node.of_offset, + return dm_scan_fdt_node(gd->dm_root, blob, node.of_offset, pre_reloc_only); } int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) { - int ret; + int ret, i; + const char * const nodes[] = { + "/chosen", + "/clocks", + "/firmware" + }; ret = dm_scan_fdt(blob, pre_reloc_only); if (ret) { @@ -341,16 +323,16 @@ int dm_extended_scan_fdt(const void *blob, bool pre_reloc_only) return ret; } - ret = dm_scan_fdt_ofnode_path("/clocks", pre_reloc_only); - if (ret) { - debug("scan for /clocks failed: %d\n", ret); - return ret; + /* 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); + if (ret) { + debug("dm_scan_fdt() scan for %s failed: %d\n", + nodes[i], ret); + return ret; + } } - ret = dm_scan_fdt_ofnode_path("/firmware", pre_reloc_only); - if (ret) - debug("scan for /firmware failed: %d\n", ret); - return ret; } #endif diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 58b19a4210..6849302936 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -118,12 +118,12 @@ int uclass_destroy(struct uclass *uc) while (!list_empty(&uc->dev_head)) { dev = list_first_entry(&uc->dev_head, struct udevice, uclass_node); - ret = device_remove(dev, DM_REMOVE_NORMAL); + ret = device_remove(dev, DM_REMOVE_NORMAL | DM_REMOVE_NO_PD); if (ret) - return ret; + return log_msg_ret("remove", ret); ret = device_unbind(dev); if (ret) - return ret; + return log_msg_ret("unbind", ret); } uc_drv = uc->uc_drv; diff --git a/drivers/core/util.c b/drivers/core/util.c index 69f83755f0..25b0d76f43 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -33,34 +33,6 @@ int list_count_items(struct list_head *head) return count; } -#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) -bool dm_ofnode_pre_reloc(ofnode node) -{ -#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD) - /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass - * had property dm-pre-reloc or u-boot,dm-spl/tpl. - * They are removed in final dtb (fdtgrep 2nd pass) - */ - return true; -#else - if (ofnode_read_bool(node, "u-boot,dm-pre-reloc")) - return true; - if (ofnode_read_bool(node, "u-boot,dm-pre-proper")) - return true; - - /* - * In regular builds individual spl and tpl handling both - * count as handled pre-relocation for later second init. - */ - if (ofnode_read_bool(node, "u-boot,dm-spl") || - ofnode_read_bool(node, "u-boot,dm-tpl")) - return true; - - return false; -#endif -} -#endif - #if !CONFIG_IS_ENABLED(OF_PLATDATA) int pci_get_devfn(struct udevice *dev) { diff --git a/drivers/misc/p2sb_emul.c b/drivers/misc/p2sb_emul.c index a6ee9a235e..02f7a7ea67 100644 --- a/drivers/misc/p2sb_emul.c +++ b/drivers/misc/p2sb_emul.c @@ -215,7 +215,7 @@ static int sandbox_p2sb_emul_map_physmem(struct udevice *dev, void **ptrp) { struct p2sb_emul_priv *priv = dev_get_priv(dev); - struct udevice *child; + struct udevice *child = NULL; /* Silence compiler warning */ unsigned int offset; int barnum; int ret; diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 30f9b8c939..7703c67492 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -162,6 +162,7 @@ int serial_init(void) #if CONFIG_IS_ENABLED(SERIAL_PRESENT) serial_find_console_or_panic(); gd->flags |= GD_FLG_SERIAL_READY; + serial_setbrg(); #endif return 0; |