summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-07-10 10:29:14 -0400
committerTom Rini <trini@konsulko.com>2018-07-10 10:29:14 -0400
commite3396ffd720877976141fa0b76a0b8ee9643d7d1 (patch)
tree7baee90ec8c5759a420f37a796b91fc77f69e7c7 /drivers
parent495c70f9dfad1a5428ec84b52e8667ea4760ecd6 (diff)
parent16b8d6b76992690c65c58dc8b0591496cc5e46ef (diff)
Merge git://git.denx.de/u-boot-dm
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/device.c8
-rw-r--r--drivers/core/of_access.c20
-rw-r--r--drivers/core/of_extra.c89
-rw-r--r--drivers/core/ofnode.c44
-rw-r--r--drivers/core/uclass.c14
-rw-r--r--drivers/misc/cros_ec.c4
-rw-r--r--drivers/mtd/spi/sandbox.c9
7 files changed, 176 insertions, 12 deletions
diff --git a/drivers/core/device.c b/drivers/core/device.c
index e048e1a659..d5f5fc31b0 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -230,6 +230,14 @@ int device_bind(struct udevice *parent, const struct driver *drv,
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,
+ devp);
+}
+
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c
index 9a50f559de..0729dfcdb3 100644
--- a/drivers/core/of_access.c
+++ b/drivers/core/of_access.c
@@ -457,6 +457,26 @@ int of_read_u32_array(const struct device_node *np, const char *propname,
return 0;
}
+int of_read_u64(const struct device_node *np, const char *propname, u64 *outp)
+{
+ const __be64 *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 = be64_to_cpup(val);
+ debug("%#llx (%lld)\n", (unsigned long long)*outp,
+ (unsigned long long)*outp);
+
+ return 0;
+}
+
int of_property_match_string(const struct device_node *np, const char *propname,
const char *string)
{
diff --git a/drivers/core/of_extra.c b/drivers/core/of_extra.c
index c76177c529..aa48917ddd 100644
--- a/drivers/core/of_extra.c
+++ b/drivers/core/of_extra.c
@@ -10,15 +10,15 @@
#include <dm/of_extra.h>
#include <dm/ofnode.h>
-int of_read_fmap_entry(ofnode node, const char *name,
- struct fmap_entry *entry)
+int ofnode_read_fmap_entry(ofnode node, struct fmap_entry *entry)
{
const char *prop;
u32 reg[2];
if (ofnode_read_u32_array(node, "reg", reg, 2)) {
- debug("Node '%s' has bad/missing 'reg' property\n", name);
- return -FDT_ERR_NOTFOUND;
+ debug("Node '%s' has bad/missing 'reg' property\n",
+ ofnode_get_name(node));
+ return -log_ret(ENOENT);
}
entry->offset = reg[0];
entry->length = reg[1];
@@ -34,3 +34,84 @@ int of_read_fmap_entry(ofnode node, const char *name,
return 0;
}
+
+int ofnode_decode_region(ofnode node, const char *prop_name, fdt_addr_t *basep,
+ fdt_size_t *sizep)
+{
+ const fdt_addr_t *cell;
+ int len;
+
+ debug("%s: %s: %s\n", __func__, ofnode_get_name(node), prop_name);
+ cell = ofnode_get_property(node, prop_name, &len);
+ if (!cell || (len < sizeof(fdt_addr_t) * 2)) {
+ debug("cell=%p, len=%d\n", cell, len);
+ return -1;
+ }
+
+ *basep = fdt_addr_to_cpu(*cell);
+ *sizep = fdt_size_to_cpu(cell[1]);
+ debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep,
+ (ulong)*sizep);
+
+ return 0;
+}
+
+int ofnode_decode_memory_region(ofnode config_node, const char *mem_type,
+ const char *suffix, fdt_addr_t *basep,
+ fdt_size_t *sizep)
+{
+ char prop_name[50];
+ const char *mem;
+ fdt_size_t size, offset_size;
+ fdt_addr_t base, offset;
+ ofnode node;
+
+ if (!ofnode_valid(config_node)) {
+ config_node = ofnode_path("/config");
+ if (!ofnode_valid(config_node)) {
+ debug("%s: Cannot find /config node\n", __func__);
+ return -ENOENT;
+ }
+ }
+ if (!suffix)
+ suffix = "";
+
+ snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type,
+ suffix);
+ mem = ofnode_read_string(config_node, prop_name);
+ if (!mem) {
+ debug("%s: No memory type for '%s', using /memory\n", __func__,
+ prop_name);
+ mem = "/memory";
+ }
+
+ node = ofnode_path(mem);
+ if (!ofnode_valid(node)) {
+ debug("%s: Failed to find node '%s'\n", __func__, mem);
+ return -ENOENT;
+ }
+
+ /*
+ * Not strictly correct - the memory may have multiple banks. We just
+ * use the first
+ */
+ if (ofnode_decode_region(node, "reg", &base, &size)) {
+ debug("%s: Failed to decode memory region %s\n", __func__,
+ mem);
+ return -EINVAL;
+ }
+
+ snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type,
+ suffix);
+ if (ofnode_decode_region(config_node, prop_name, &offset,
+ &offset_size)) {
+ debug("%s: Failed to decode memory region '%s'\n", __func__,
+ prop_name);
+ return -EINVAL;
+ }
+
+ *basep = base + offset;
+ *sizep = offset_size;
+
+ return 0;
+}
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 3cf3205a2f..29375397e0 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -55,6 +55,38 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
return def;
}
+int ofnode_read_u64(ofnode node, const char *propname, u64 *outp)
+{
+ const fdt64_t *cell;
+ int len;
+
+ assert(ofnode_valid(node));
+ debug("%s: %s: ", __func__, propname);
+
+ if (ofnode_is_np(node))
+ return of_read_u64(ofnode_to_np(node), propname, outp);
+
+ cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
+ &len);
+ if (!cell || len < sizeof(*cell)) {
+ debug("(not found)\n");
+ return -EINVAL;
+ }
+ *outp = fdt64_to_cpu(cell[0]);
+ debug("%#llx (%lld)\n", (unsigned long long)*outp,
+ (unsigned long long)*outp);
+
+ return 0;
+}
+
+int ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
+{
+ assert(ofnode_valid(node));
+ ofnode_read_u64(node, propname, &def);
+
+ return def;
+}
+
bool ofnode_read_bool(ofnode node, const char *propname)
{
const void *prop;
@@ -697,3 +729,15 @@ int ofnode_device_is_compatible(ofnode node, const char *compat)
ofnode_to_offset(node),
compat);
}
+
+ofnode ofnode_by_compatible(ofnode from, const char *compat)
+{
+ if (of_live_active()) {
+ return np_to_ofnode(of_find_compatible_node(
+ (struct device_node *)ofnode_to_np(from), NULL,
+ compat));
+ } else {
+ return offset_to_ofnode(fdt_node_offset_by_compatible(
+ gd->fdt_blob, ofnode_to_offset(from), compat));
+ }
+}
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 0085d3fb24..d609b170e1 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -308,6 +308,7 @@ int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
struct udevice *dev;
int ret;
+ log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node));
*devp = NULL;
if (!ofnode_valid(node))
return -ENODEV;
@@ -316,13 +317,19 @@ int uclass_find_device_by_ofnode(enum uclass_id id, ofnode node,
return ret;
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+ log(LOGC_DM, LOGL_DEBUG_CONTENT, " - checking %s\n",
+ dev->name);
if (ofnode_equal(dev_ofnode(dev), node)) {
*devp = dev;
- return 0;
+ goto done;
}
}
+ ret = -ENODEV;
- return -ENODEV;
+done:
+ log(LOGC_DM, LOGL_DEBUG, " - result for %s: %s (ret=%d)\n",
+ ofnode_get_name(node), *devp ? (*devp)->name : "(none)", ret);
+ return ret;
}
#if CONFIG_IS_ENABLED(OF_CONTROL)
@@ -449,8 +456,11 @@ int uclass_get_device_by_ofnode(enum uclass_id id, ofnode node,
struct udevice *dev;
int ret;
+ log(LOGC_DM, LOGL_DEBUG, "Looking for %s\n", ofnode_get_name(node));
*devp = NULL;
ret = uclass_find_device_by_ofnode(id, node, &dev);
+ log(LOGC_DM, LOGL_DEBUG, " - result for %s: %s (ret=%d)\n",
+ ofnode_get_name(node), dev ? dev->name : "(none)", ret);
return uclass_get_device_tail(dev, ret, devp);
}
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 5fd2cd9973..6f299d407a 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -1028,7 +1028,7 @@ int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config)
return -1;
}
- if (of_read_fmap_entry(flash_node, "flash", &config->flash)) {
+ if (ofnode_read_fmap_entry(flash_node, &config->flash)) {
debug("Failed to decode flash node in chrome-ec\n");
return -1;
}
@@ -1050,7 +1050,7 @@ int cros_ec_decode_ec_flash(struct udevice *dev, struct fdt_cros_ec *config)
return -1;
}
- if (of_read_fmap_entry(node, "reg", &config->region[region])) {
+ if (ofnode_read_fmap_entry(node, &config->region[region])) {
debug("Failed to decode flash region in chrome-ec'\n");
return -1;
}
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index f23c0e13e0..1b6c028251 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -556,7 +556,7 @@ static int sandbox_cmdline_cb_spi_sf(struct sandbox_state *state,
SANDBOX_CMDLINE_OPT(spi_sf, 1, "connect a SPI flash: <bus>:<cs>:<id>:<file>");
int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
- struct udevice *bus, int of_offset, const char *spec)
+ struct udevice *bus, ofnode node, const char *spec)
{
struct udevice *emul;
char name[20], *str;
@@ -575,7 +575,7 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
str = strdup(name);
if (!str)
return -ENOMEM;
- ret = device_bind(bus, drv, str, NULL, of_offset, &emul);
+ ret = device_bind_ofnode(bus, drv, str, NULL, node, &emul);
if (ret) {
free(str);
printf("Cannot create emul device for spec '%s' (err=%d)\n",
@@ -620,7 +620,8 @@ static int sandbox_sf_bind_bus_cs(struct sandbox_state *state, int busnum,
if (ret)
return ret;
- return sandbox_sf_bind_emul(state, busnum, cs, bus, -1, spec);
+ return sandbox_sf_bind_emul(state, busnum, cs, bus, ofnode_null(),
+ spec);
}
int sandbox_spi_get_emul(struct sandbox_state *state,
@@ -638,7 +639,7 @@ int sandbox_spi_get_emul(struct sandbox_state *state,
debug("%s: busnum=%u, cs=%u: binding SPI flash emulation: ",
__func__, busnum, cs);
ret = sandbox_sf_bind_emul(state, busnum, cs, bus,
- dev_of_offset(slave), slave->name);
+ dev_ofnode(slave), slave->name);
if (ret) {
debug("failed (err=%d)\n", ret);
return ret;