2 * OF NUMA Parsing support.
4 * Copyright (C) 2015 - 2016 Cavium Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/of_address.h>
21 #include <linux/nodemask.h>
25 /* define default numa node to 0 */
26 #define DEFAULT_NODE 0
29 * Even though we connect cpus to numa domains later in SMP
30 * init, we need to know the node ids now for all cpus.
32 static void __init
of_numa_parse_cpu_nodes(void)
36 struct device_node
*cpus
;
37 struct device_node
*np
= NULL
;
39 cpus
= of_find_node_by_path("/cpus");
43 for_each_child_of_node(cpus
, np
) {
44 /* Skip things that are not CPUs */
45 if (of_node_cmp(np
->type
, "cpu") != 0)
48 r
= of_property_read_u32(np
, "numa-node-id", &nid
);
52 pr_debug("NUMA: CPU on %u\n", nid
);
53 if (nid
>= MAX_NUMNODES
)
54 pr_warn("NUMA: Node id %u exceeds maximum value\n",
57 node_set(nid
, numa_nodes_parsed
);
61 static int __init
of_numa_parse_memory_nodes(void)
63 struct device_node
*np
= NULL
;
69 np
= of_find_node_by_type(np
, "memory");
73 r
= of_property_read_u32(np
, "numa-node-id", &nid
);
76 * property doesn't exist if -EINVAL, continue
77 * looking for more memory nodes with
78 * "numa-node-id" property
82 /* some other error */
85 r
= of_address_to_resource(np
, 0, &rsrc
);
87 pr_err("NUMA: bad reg property in memory node\n");
91 pr_debug("NUMA: base = %llx len = %llx, node = %u\n",
92 rsrc
.start
, rsrc
.end
- rsrc
.start
+ 1, nid
);
94 r
= numa_add_memblk(nid
, rsrc
.start
,
95 rsrc
.end
- rsrc
.start
+ 1);
104 static int __init
of_numa_parse_distance_map_v1(struct device_node
*map
)
106 const __be32
*matrix
;
110 pr_info("NUMA: parsing numa-distance-map-v1\n");
112 matrix
= of_get_property(map
, "distance-matrix", NULL
);
114 pr_err("NUMA: No distance-matrix property in distance-map\n");
118 entry_count
= of_property_count_u32_elems(map
, "distance-matrix");
119 if (entry_count
<= 0) {
120 pr_err("NUMA: Invalid distance-matrix\n");
124 for (i
= 0; i
+ 2 < entry_count
; i
+= 3) {
125 u32 nodea
, nodeb
, distance
;
127 nodea
= of_read_number(matrix
, 1);
129 nodeb
= of_read_number(matrix
, 1);
131 distance
= of_read_number(matrix
, 1);
134 numa_set_distance(nodea
, nodeb
, distance
);
135 pr_debug("NUMA: distance[node%d -> node%d] = %d\n",
136 nodea
, nodeb
, distance
);
138 /* Set default distance of node B->A same as A->B */
140 numa_set_distance(nodeb
, nodea
, distance
);
146 static int __init
of_numa_parse_distance_map(void)
149 struct device_node
*np
;
151 np
= of_find_compatible_node(NULL
, NULL
,
152 "numa-distance-map-v1");
154 ret
= of_numa_parse_distance_map_v1(np
);
160 int of_node_to_nid(struct device_node
*device
)
162 struct device_node
*np
;
166 np
= of_node_get(device
);
169 struct device_node
*parent
;
171 r
= of_property_read_u32(np
, "numa-node-id", &nid
);
173 * -EINVAL indicates the property was not found, and
174 * we walk up the tree trying to find a parent with a
175 * "numa-node-id". Any other type of error indicates
176 * a bad device tree and we give up.
181 parent
= of_get_parent(np
);
186 pr_warn("NUMA: Invalid \"numa-node-id\" property in node %s\n",
191 if (nid
>= MAX_NUMNODES
)
192 pr_warn("NUMA: Node id %u exceeds maximum value\n",
200 EXPORT_SYMBOL(of_node_to_nid
);
202 int __init
of_numa_init(void)
206 of_numa_parse_cpu_nodes();
207 r
= of_numa_parse_memory_nodes();
210 return of_numa_parse_distance_map();