struct fragment {
        struct device_node *target;
        struct device_node *overlay;
-       bool is_symbols_node;
 };
 
 /**
  * struct overlay_changeset
- * @ovcs_list: list on which we are located
- * @count:     count of @fragments structures
- * @fragments: info about fragment nodes in overlay expanded device tree
- * @cset:      changeset to apply fragments to live device tree
+ * @ovcs_list:         list on which we are located
+ * @count:             count of fragment structures
+ * @fragments:         fragment nodes in the overlay expanded device tree
+ * @symbols_fragment:  last element of @fragments[] is the  __symbols__ node
+ * @cset:              changeset to apply fragments to live device tree
  */
 struct overlay_changeset {
        int id;
        struct list_head ovcs_list;
        int count;
        struct fragment *fragments;
+       bool symbols_fragment;
        struct of_changeset cset;
 };
 
 
 static int build_changeset_next_level(struct overlay_changeset *ovcs,
                struct device_node *target_node,
-               const struct device_node *overlay_node,
-               bool is_symbols_node);
+               const struct device_node *overlay_node);
 
 /*
  * of_resolve_phandles() finds the largest phandle in the live tree.
  * @ovcs:              overlay changeset
  * @target_node:       where to place @overlay_prop in live tree
  * @overlay_prop:      property to add or update, from overlay tree
- * is_symbols_node:    1 if @target_node is "/__symbols__"
+ * @is_symbols_prop:   1 if @overlay_prop is from node "/__symbols__"
  *
  * If @overlay_prop does not already exist in @target_node, add changeset entry
  * to add @overlay_prop in @target_node, else add changeset entry to update
 static int add_changeset_property(struct overlay_changeset *ovcs,
                struct device_node *target_node,
                struct property *overlay_prop,
-               bool is_symbols_node)
+               bool is_symbols_prop)
 {
        struct property *new_prop = NULL, *prop;
        int ret = 0;
            !of_prop_cmp(overlay_prop->name, "linux,phandle"))
                return 0;
 
-       if (is_symbols_node) {
+       if (is_symbols_prop) {
                if (prop)
                        return -EINVAL;
                new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
                if (ret)
                        return ret;
 
-               return build_changeset_next_level(ovcs, tchild, node, 0);
+               return build_changeset_next_level(ovcs, tchild, node);
        }
 
        if (node->phandle && tchild->phandle)
                ret = -EINVAL;
        else
-               ret = build_changeset_next_level(ovcs, tchild, node, 0);
+               ret = build_changeset_next_level(ovcs, tchild, node);
        of_node_put(tchild);
 
        return ret;
  * @ovcs:              overlay changeset
  * @target_node:       where to place @overlay_node in live tree
  * @overlay_node:      node from within an overlay device tree fragment
- * @is_symbols_node:   @overlay_node is node "/__symbols__"
  *
  * Add the properties (if any) and nodes (if any) from @overlay_node to the
  * @ovcs->cset changeset.  If an added node has child nodes, they will
  */
 static int build_changeset_next_level(struct overlay_changeset *ovcs,
                struct device_node *target_node,
-               const struct device_node *overlay_node,
-               bool is_symbols_node)
+               const struct device_node *overlay_node)
 {
        struct device_node *child;
        struct property *prop;
        int ret;
 
        for_each_property_of_node(overlay_node, prop) {
-               ret = add_changeset_property(ovcs, target_node, prop,
-                                            is_symbols_node);
+               ret = add_changeset_property(ovcs, target_node, prop, 0);
                if (ret) {
                        pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
                                 target_node, prop->name, ret);
                }
        }
 
-       if (is_symbols_node)
-               return 0;
-
        for_each_child_of_node(overlay_node, child) {
                ret = add_changeset_node(ovcs, target_node, child);
                if (ret) {
        return 0;
 }
 
+/*
+ * Add the properties from __overlay__ node to the @ovcs->cset changeset.
+ */
+static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
+               struct device_node *target_node,
+               const struct device_node *overlay_symbols_node)
+{
+       struct property *prop;
+       int ret;
+
+       for_each_property_of_node(overlay_symbols_node, prop) {
+               ret = add_changeset_property(ovcs, target_node, prop, 1);
+               if (ret) {
+                       pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
+                                target_node, prop->name, ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments
  * @ovcs:      Overlay changeset
  */
 static int build_changeset(struct overlay_changeset *ovcs)
 {
-       int i, ret;
+       struct fragment *fragment;
+       int fragments_count, i, ret;
 
-       for (i = 0; i < ovcs->count; i++) {
-               struct fragment *fragment = &ovcs->fragments[i];
+       /*
+        * if there is a symbols fragment in ovcs->fragments[i] it is
+        * the final element in the array
+        */
+       if (ovcs->symbols_fragment)
+               fragments_count = ovcs->count - 1;
+       else
+               fragments_count = ovcs->count;
+
+       for (i = 0; i < fragments_count; i++) {
+               fragment = &ovcs->fragments[i];
 
                ret = build_changeset_next_level(ovcs, fragment->target,
-                                              fragment->overlay,
-                                              fragment->is_symbols_node);
+                                                fragment->overlay);
+               if (ret) {
+                       pr_debug("apply failed '%pOF'\n", fragment->target);
+                       return ret;
+               }
+       }
+
+       if (ovcs->symbols_fragment) {
+               fragment = &ovcs->fragments[ovcs->count - 1];
+               ret = build_changeset_symbols_node(ovcs, fragment->target,
+                                                  fragment->overlay);
                if (ret) {
                        pr_debug("apply failed '%pOF'\n", fragment->target);
                        return ret;
                }
        }
 
+       /*
+        * if there is a symbols fragment in ovcs->fragments[i] it is
+        * the final element in the array
+        */
        node = of_get_child_by_name(tree, "__symbols__");
        if (node) {
+               ovcs->symbols_fragment = 1;
                fragment = &fragments[cnt];
                fragment->overlay = node;
                fragment->target = of_find_node_by_path("/__symbols__");
-               fragment->is_symbols_node = 1;
 
                if (!fragment->target) {
                        pr_err("no symbols in root of device tree.\n");