fdtdec: Support parsing multiple /memory nodes
authorMarek Vasut <marek.vasut+renesas@gmail.com>
Mon, 27 Nov 2017 04:32:42 +0000 (05:32 +0100)
committerMarek Vasut <marek.vasut+renesas@gmail.com>
Thu, 30 Nov 2017 01:32:33 +0000 (02:32 +0100)
It is legal to have multiple /memory nodes in a device tree . Currently,
fdtdec_setup_memory_size() only supports parsing the first node . This
patch extends the function such that if a particular /memory node does
no longer have further "reg" entries and CONFIG_NR_DRAM_BANKS still
allows for more DRAM banks, the code moves on to the next memory node
and checks it's "reg"s. This makes it possible to handle both systems
with single memory node with multiple entries and systems with multiple
memory nodes with single entry.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
Cc: Simon Glass <sjg@chromium.org>
lib/fdtdec.c

index c4582eaccae7ae8c96dade8a46b21c2183b9e07a..46df0f15f9c2cac54c6637967cacdbed3c242f97 100644 (file)
@@ -1176,21 +1176,33 @@ int fdtdec_setup_memory_size(void)
 #if defined(CONFIG_NR_DRAM_BANKS)
 int fdtdec_setup_memory_banksize(void)
 {
-       int bank, ret, mem;
+       int bank, ret, mem, reg = 0;
        struct fdt_resource res;
 
-       mem = fdt_path_offset(gd->fdt_blob, "/memory");
+       mem = fdt_node_offset_by_prop_value(gd->fdt_blob, -1, "device_type",
+                                           "memory", 7);
        if (mem < 0) {
                debug("%s: Missing /memory node\n", __func__);
                return -EINVAL;
        }
 
        for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
-               ret = fdt_get_resource(gd->fdt_blob, mem, "reg", bank, &res);
-               if (ret == -FDT_ERR_NOTFOUND)
-                       break;
-               if (ret != 0)
+               ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+               if (ret == -FDT_ERR_NOTFOUND) {
+                       reg = 0;
+                       mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
+                                                           "device_type",
+                                                           "memory", 7);
+                       if (mem == -FDT_ERR_NOTFOUND)
+                               break;
+
+                       ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
+                       if (ret == -FDT_ERR_NOTFOUND)
+                               break;
+               }
+               if (ret != 0) {
                        return -EINVAL;
+               }
 
                gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
                gd->bd->bi_dram[bank].size =