[PATCH] Have ia64 use add_active_range() and free_area_init_nodes
[sfrench/cifs-2.6.git] / arch / ia64 / mm / init.c
index 11f08001f8c26e9aaa820b37d379d78eedac0bbd..ff87a5cba399f873348858fa7775a608ab2c3fb7 100644 (file)
@@ -4,7 +4,6 @@
  * Copyright (C) 1998-2003 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
@@ -416,6 +415,61 @@ ia64_mmu_init (void *my_cpu_data)
 }
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
+int vmemmap_find_next_valid_pfn(int node, int i)
+{
+       unsigned long end_address, hole_next_pfn;
+       unsigned long stop_address;
+       pg_data_t *pgdat = NODE_DATA(node);
+
+       end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i];
+       end_address = PAGE_ALIGN(end_address);
+
+       stop_address = (unsigned long) &vmem_map[
+               pgdat->node_start_pfn + pgdat->node_spanned_pages];
+
+       do {
+               pgd_t *pgd;
+               pud_t *pud;
+               pmd_t *pmd;
+               pte_t *pte;
+
+               pgd = pgd_offset_k(end_address);
+               if (pgd_none(*pgd)) {
+                       end_address += PGDIR_SIZE;
+                       continue;
+               }
+
+               pud = pud_offset(pgd, end_address);
+               if (pud_none(*pud)) {
+                       end_address += PUD_SIZE;
+                       continue;
+               }
+
+               pmd = pmd_offset(pud, end_address);
+               if (pmd_none(*pmd)) {
+                       end_address += PMD_SIZE;
+                       continue;
+               }
+
+               pte = pte_offset_kernel(pmd, end_address);
+retry_pte:
+               if (pte_none(*pte)) {
+                       end_address += PAGE_SIZE;
+                       pte++;
+                       if ((end_address < stop_address) &&
+                           (end_address != ALIGN(end_address, 1UL << PMD_SHIFT)))
+                               goto retry_pte;
+                       continue;
+               }
+               /* Found next valid vmem_map page */
+               break;
+       } while (end_address < stop_address);
+
+       end_address = min(end_address, stop_address);
+       end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1;
+       hole_next_pfn = end_address / sizeof(struct page);
+       return hole_next_pfn - pgdat->node_start_pfn;
+}
 
 int __init
 create_mem_map_page_table (u64 start, u64 end, void *arg)
@@ -539,6 +593,18 @@ find_largest_hole (u64 start, u64 end, void *arg)
        last_end = end;
        return 0;
 }
+
+int __init
+register_active_ranges(u64 start, u64 end, void *nid)
+{
+       BUG_ON(nid == NULL);
+       BUG_ON(*(unsigned long *)nid >= MAX_NUMNODES);
+
+       add_active_range(*(unsigned long *)nid,
+                               __pa(start) >> PAGE_SHIFT,
+                               __pa(end) >> PAGE_SHIFT);
+       return 0;
+}
 #endif /* CONFIG_VIRTUAL_MEM_MAP */
 
 static int __init
@@ -652,7 +718,7 @@ void online_page(struct page *page)
        num_physpages++;
 }
 
-int add_memory(u64 start, u64 size)
+int arch_add_memory(int nid, u64 start, u64 size)
 {
        pg_data_t *pgdat;
        struct zone *zone;
@@ -660,7 +726,7 @@ int add_memory(u64 start, u64 size)
        unsigned long nr_pages = size >> PAGE_SHIFT;
        int ret;
 
-       pgdat = NODE_DATA(0);
+       pgdat = NODE_DATA(nid);
 
        zone = pgdat->node_zones + ZONE_NORMAL;
        ret = __add_pages(zone, start_pfn, nr_pages);
@@ -671,7 +737,6 @@ int add_memory(u64 start, u64 size)
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(add_memory);
 
 int remove_memory(u64 start, u64 size)
 {