summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMario Six <mario.six@gdsys.cc>2018-03-12 14:53:33 +0100
committerYe Li <ye.li@nxp.com>2018-04-26 02:26:13 -0700
commita315da0f3fc3969e5e0437e1555e63a7061d645a (patch)
tree02c0a9b54f64e53bc88c7c3eebb9349ccfad9664 /drivers
parentf95ab1fb6e37f0601f397091bb011edf7a98b890 (diff)
core: ofnode: Fix translation for #size-cells == 0
Commit 286ede6 ("drivers: core: Add translation in live tree case") made dev_get_addr always use proper bus translations for addresses read from the device tree. But this leads to problems with certain busses, e.g. I2C busses, which run into an error during translation, and hence stop working. It turns out that of_translate_address() and fdt_translate_address() stop the address translation with an error when they're asked to translate addresses for busses where #size-cells == 0 (comment from drivers/core/of_addr.c): * Note: We consider that crossing any level with #size-cells == 0 to mean * that translation is impossible (that is we are not dealing with a value * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things To fix this case, we check in both the live-tree and non-live tree-case, whether the bus of the device whose address is about to be translated has size-cell size zero. If this is the case, we just read the address as a plain integer and return it, and only apply bus translations if the size-cell size if greater than zero. Signed-off-by: Mario Six <mario.six@gdsys.cc> Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com> Reported-by: Martin Fuzzey <mfuzzey@parkeon.com> Fixes: 286ede6 ("drivers: core: Add translation in live tree case") Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/core/fdtaddr.c17
-rw-r--r--drivers/core/ofnode.c5
2 files changed, 15 insertions, 7 deletions
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index 3847dd836e3..9a3b4c312af 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -49,12 +49,17 @@ fdt_addr_t devfdt_get_addr_index(struct udevice *dev, int index)
reg += index * (na + ns);
- /*
- * Use the full-fledged translate function for complex
- * bus setups.
- */
- addr = fdt_translate_address((void *)gd->fdt_blob,
- dev_of_offset(dev), reg);
+ if (ns) {
+ /*
+ * Use the full-fledged translate function for complex
+ * bus setups.
+ */
+ addr = fdt_translate_address((void *)gd->fdt_blob,
+ dev_of_offset(dev), reg);
+ } else {
+ /* Non translatable if #size-cells == 0 */
+ addr = fdt_read_number(reg, na);
+ }
} else {
/*
* Use the "simple" translate function for less complex
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index 4e4532651fc..5909a25f856 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -227,13 +227,16 @@ fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
uint flags;
u64 size;
int na;
+ int ns;
prop_val = of_get_address(ofnode_to_np(node), index, &size,
&flags);
if (!prop_val)
return FDT_ADDR_T_NONE;
- if (IS_ENABLED(CONFIG_OF_TRANSLATE)) {
+ ns = of_n_size_cells(ofnode_to_np(node));
+
+ if (IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
return of_translate_address(ofnode_to_np(node), prop_val);
} else {
na = of_n_addr_cells(ofnode_to_np(node));