diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index 0a111eced6f1b86aeedd7fffa2aa4b5847efcc30..2e0b9c04e209e2b9b5297886c66152445b34b676 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -272,6 +272,33 @@ class DtbPlatdata:
             upto += 1
         return structs
 
+    def ScanPhandles(self):
+        """Figure out what phandles each node uses
+
+        We need to be careful when outputing nodes that use phandles since
+        they must come after the declaration of the phandles in the C file.
+        Otherwise we get a compiler error since the phandle struct is not yet
+        declared.
+
+        This function adds to each node a list of phandle nodes that the node
+        depends on. This allows us to output things in the right order.
+        """
+        for node in self._valid_nodes:
+            node.phandles = set()
+            for pname, prop in node.props.items():
+                if pname in PROP_IGNORE_LIST or pname[0] == '#':
+                    continue
+                if type(prop.value) == list:
+                    if self.IsPhandle(prop):
+                        # Process the list as pairs of (phandle, id)
+                        it = iter(prop.value)
+                        for phandle_cell, id_cell in zip(it, it):
+                            phandle = fdt_util.fdt32_to_cpu(phandle_cell)
+                            id = fdt_util.fdt32_to_cpu(id_cell)
+                            target_node = self._phandle_node[phandle]
+                            node.phandles.add(target_node)
+
+
     def GenerateStructs(self, structs):
         """Generate struct defintions for the platform data
 
@@ -352,6 +379,8 @@ class DtbPlatdata:
         self.Buf('};\n')
         self.Buf('\n')
 
+        self.Out(''.join(self.GetBuf()))
+
     def GenerateTables(self):
         """Generate device defintions for the platform data
 
@@ -363,21 +392,18 @@ class DtbPlatdata:
         self.Out('#include <dm.h>\n')
         self.Out('#include <dt-structs.h>\n')
         self.Out('\n')
-        node_txt_list = []
-        for node in self._valid_nodes:
+        nodes_to_output = list(self._valid_nodes)
+
+        # Keep outputing nodes until there is none left
+        while nodes_to_output:
+            node = nodes_to_output[0]
+            # Output all the node's dependencies first
+            for req_node in node.phandles:
+                if req_node in nodes_to_output:
+                    self.OutputNode(req_node)
+                    nodes_to_output.remove(req_node)
             self.OutputNode(node)
-
-            # Output phandle target nodes first, since they may be referenced
-            # by others
-            if 'phandle' in node.props:
-                self.Out(''.join(self.GetBuf()))
-            else:
-                node_txt_list.append(self.GetBuf())
-
-        # Output all the nodes which are not phandle targets themselves, but
-        # may reference them. This avoids the need for forward declarations.
-        for node_txt in node_txt_list:
-            self.Out(''.join(node_txt))
+            nodes_to_output.remove(node)
 
 
 if __name__ != "__main__":
@@ -400,6 +426,7 @@ plat.ScanDtb()
 plat.ScanTree()
 plat.SetupOutput(options.output)
 structs = plat.ScanStructs()
+plat.ScanPhandles()
 
 for cmd in args[0].split(','):
     if cmd == 'struct':