Merge branch 'master' into x86/memblock
[pandora-kernel.git] / arch / powerpc / mm / numa.c
index 2164006..261adbd 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/mmzone.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/nodemask.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
@@ -127,45 +127,25 @@ static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
 }
 
 /*
- * get_active_region_work_fn - A helper function for get_node_active_region
- *     Returns datax set to the start_pfn and end_pfn if they contain
- *     the initial value of datax->start_pfn between them
- * @start_pfn: start page(inclusive) of region to check
- * @end_pfn: end page(exclusive) of region to check
- * @datax: comes in with ->start_pfn set to value to search for and
- *     goes out with active range if it contains it
- * Returns 1 if search value is in range else 0
- */
-static int __init get_active_region_work_fn(unsigned long start_pfn,
-                                       unsigned long end_pfn, void *datax)
-{
-       struct node_active_region *data;
-       data = (struct node_active_region *)datax;
-
-       if (start_pfn <= data->start_pfn && end_pfn > data->start_pfn) {
-               data->start_pfn = start_pfn;
-               data->end_pfn = end_pfn;
-               return 1;
-       }
-       return 0;
-
-}
-
-/*
- * get_node_active_region - Return active region containing start_pfn
+ * get_node_active_region - Return active region containing pfn
  * Active range returned is empty if none found.
- * @start_pfn: The page to return the region for.
- * @node_ar: Returned set to the active region containing start_pfn
+ * @pfn: The page to return the region for
+ * @node_ar: Returned set to the active region containing @pfn
  */
-static void __init get_node_active_region(unsigned long start_pfn,
-                      struct node_active_region *node_ar)
+static void __init get_node_active_region(unsigned long pfn,
+                                         struct node_active_region *node_ar)
 {
-       int nid = early_pfn_to_nid(start_pfn);
+       unsigned long start_pfn, end_pfn;
+       int i, nid;
 
-       node_ar->nid = nid;
-       node_ar->start_pfn = start_pfn;
-       node_ar->end_pfn = start_pfn;
-       work_with_active_regions(nid, get_active_region_work_fn, node_ar);
+       for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
+               if (pfn >= start_pfn && pfn < end_pfn) {
+                       node_ar->nid = nid;
+                       node_ar->start_pfn = start_pfn;
+                       node_ar->end_pfn = end_pfn;
+                       break;
+               }
+       }
 }
 
 static void map_cpu_to_node(int cpu, int node)
@@ -315,7 +295,10 @@ static int __init find_min_common_depth(void)
        struct device_node *root;
        const char *vec5;
 
-       root = of_find_node_by_path("/rtas");
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               root = of_find_node_by_path("/ibm,opal");
+       else
+               root = of_find_node_by_path("/rtas");
        if (!root)
                root = of_find_node_by_path("/");
 
@@ -344,12 +327,19 @@ static int __init find_min_common_depth(void)
 
 #define VEC5_AFFINITY_BYTE     5
 #define VEC5_AFFINITY          0x80
-       chosen = of_find_node_by_path("/chosen");
-       if (chosen) {
-               vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
-               if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
-                       dbg("Using form 1 affinity\n");
-                       form1_affinity = 1;
+
+       if (firmware_has_feature(FW_FEATURE_OPAL))
+               form1_affinity = 1;
+       else {
+               chosen = of_find_node_by_path("/chosen");
+               if (chosen) {
+                       vec5 = of_get_property(chosen,
+                                              "ibm,architecture-vec-5", NULL);
+                       if (vec5 && (vec5[VEC5_AFFINITY_BYTE] &
+                                                       VEC5_AFFINITY)) {
+                               dbg("Using form 1 affinity\n");
+                               form1_affinity = 1;
+                       }
                }
        }
 
@@ -709,8 +699,7 @@ static void __init parse_drconf_memory(struct device_node *memory)
 
 static int __init parse_numa_properties(void)
 {
-       struct device_node *cpu = NULL;
-       struct device_node *memory = NULL;
+       struct device_node *memory;
        int default_nid = 0;
        unsigned long i;
 
@@ -732,6 +721,7 @@ static int __init parse_numa_properties(void)
         * each node to be onlined must have NODE_DATA etc backing it.
         */
        for_each_present_cpu(i) {
+               struct device_node *cpu;
                int nid;
 
                cpu = of_get_cpu_node(i, NULL);
@@ -750,8 +740,8 @@ static int __init parse_numa_properties(void)
        }
 
        get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
-       memory = NULL;
-       while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+
+       for_each_node_by_type(memory, "memory") {
                unsigned long start;
                unsigned long size;
                int nid;
@@ -800,8 +790,9 @@ new_range:
        }
 
        /*
-        * Now do the same thing for each MEMBLOCK listed in the ibm,dynamic-memory
-        * property in the ibm,dynamic-reconfiguration-memory node.
+        * Now do the same thing for each MEMBLOCK listed in the
+        * ibm,dynamic-memory property in the
+        * ibm,dynamic-reconfiguration-memory node.
         */
        memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
        if (memory)
@@ -1187,10 +1178,10 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
  */
 int hot_add_node_scn_to_nid(unsigned long scn_addr)
 {
-       struct device_node *memory = NULL;
+       struct device_node *memory;
        int nid = -1;
 
-       while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+       for_each_node_by_type(memory, "memory") {
                unsigned long start, size;
                int ranges;
                const unsigned int *memcell_buf;
@@ -1214,11 +1205,12 @@ int hot_add_node_scn_to_nid(unsigned long scn_addr)
                        break;
                }
 
-               of_node_put(memory);
                if (nid >= 0)
                        break;
        }
 
+       of_node_put(memory);
+
        return nid;
 }