struct memblock_type *type_b, phys_addr_t *out_start,
                          phys_addr_t *out_end, int *out_nid);
 
-void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
-                               phys_addr_t *out_end);
-
 void __memblock_free_late(phys_addr_t base, phys_addr_t size);
 
 #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
                                 MEMBLOCK_NONE, p_start, p_end, NULL)
 
 /**
- * for_each_reserved_mem_region - iterate over all reserved memblock areas
+ * for_each_reserved_mem_range - iterate over all reserved memblock areas
  * @i: u64 used as loop variable
  * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL
  * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL
  * Walks over reserved areas of memblock. Available as soon as memblock
  * is initialized.
  */
-#define for_each_reserved_mem_region(i, p_start, p_end)                        \
-       for (i = 0UL, __next_reserved_mem_region(&i, p_start, p_end);   \
-            i != (u64)ULLONG_MAX;                                      \
-            __next_reserved_mem_region(&i, p_start, p_end))
+#define for_each_reserved_mem_range(i, p_start, p_end)                 \
+       __for_each_mem_range(i, &memblock.reserved, NULL, NUMA_NO_NODE, \
+                            MEMBLOCK_NONE, p_start, p_end, NULL)
 
 static inline bool memblock_is_hotpluggable(struct memblock_region *m)
 {
 
 };
 #endif
 
+/*
+ * keep a pointer to &memblock.memory in the text section to use it in
+ * __next_mem_range() and its helpers.
+ *  For architectures that do not keep memblock data after init, this
+ * pointer will be reset to NULL at memblock_discard()
+ */
+static __refdata struct memblock_type *memblock_memory = &memblock.memory;
+
 #define for_each_memblock_type(i, memblock_type, rgn)                  \
        for (i = 0, rgn = &memblock_type->regions[0];                   \
             i < memblock_type->cnt;                                    \
                                  memblock.memory.max);
                __memblock_free_late(addr, size);
        }
+
+       memblock_memory = NULL;
 }
 #endif
 
        return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
 }
 
-/**
- * __next_reserved_mem_region - next function for for_each_reserved_region()
- * @idx: pointer to u64 loop variable
- * @out_start: ptr to phys_addr_t for start address of the region, can be %NULL
- * @out_end: ptr to phys_addr_t for end address of the region, can be %NULL
- *
- * Iterate over all reserved memory regions.
- */
-void __init_memblock __next_reserved_mem_region(u64 *idx,
-                                          phys_addr_t *out_start,
-                                          phys_addr_t *out_end)
-{
-       struct memblock_type *type = &memblock.reserved;
-
-       if (*idx < type->cnt) {
-               struct memblock_region *r = &type->regions[*idx];
-               phys_addr_t base = r->base;
-               phys_addr_t size = r->size;
-
-               if (out_start)
-                       *out_start = base;
-               if (out_end)
-                       *out_end = base + size - 1;
-
-               *idx += 1;
-               return;
-       }
-
-       /* signal end of iteration */
-       *idx = ULLONG_MAX;
-}
-
-static bool should_skip_region(struct memblock_region *m, int nid, int flags)
+static bool should_skip_region(struct memblock_type *type,
+                              struct memblock_region *m,
+                              int nid, int flags)
 {
        int m_nid = memblock_get_region_node(m);
 
+       /* we never skip regions when iterating memblock.reserved or physmem */
+       if (type != memblock_memory)
+               return false;
+
        /* only memory regions are associated with nodes, check it */
        if (nid != NUMA_NO_NODE && nid != m_nid)
                return true;
                phys_addr_t m_end = m->base + m->size;
                int         m_nid = memblock_get_region_node(m);
 
-               if (should_skip_region(m, nid, flags))
+               if (should_skip_region(type_a, m, nid, flags))
                        continue;
 
                if (!type_b) {
                phys_addr_t m_end = m->base + m->size;
                int m_nid = memblock_get_region_node(m);
 
-               if (should_skip_region(m, nid, flags))
+               if (should_skip_region(type_a, m, nid, flags))
                        continue;
 
                if (!type_b) {
 
        memblock_clear_hotplug(0, -1);
 
-       for_each_reserved_mem_region(i, &start, &end)
+       for_each_reserved_mem_range(i, &start, &end)
                reserve_bootmem_region(start, end);
 
        /*