aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2013-10-03 17:24:51 -0400
committerGrant Likely <grant.likely@linaro.org>2013-10-15 15:09:10 -0400
commitd1cb9d1af0bc11b7450a6032f43935c746609418 (patch)
tree061b56dbd9e656730262445b373bacd399c0678e
parent444c91e5720cb5b825356e32c67c2c5184d1c09a (diff)
of: Make cpu node handling more portable.
Use for_each_node_by_type() to iterate all cpu nodes in the system. Provide and overridable function arch_find_n_match_cpu_physical_id, which sees if the given device node matches 'cpu' and if so sets '*thread' when non-NULL to the cpu thread number within the core. The default implementation behaves the same as the existing code. Add a sparc64 implementation. Signed-off-by: David S. Miller <davem@davemloft.net> Tested-by: Sudeep KarkadaNagesha <Sudeep.KarkadaNagesha@arm.com> Signed-off-by: Grant Likely <grant.likely@linaro.org>
-rw-r--r--arch/sparc/kernel/prom_64.c53
-rw-r--r--drivers/of/base.c45
-rw-r--r--include/linux/cpu.h3
3 files changed, 84 insertions, 17 deletions
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index d397d7fc5c28..6b39125eb927 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -373,6 +373,59 @@ static const char *get_mid_prop(void)
373 return (tlb_type == spitfire ? "upa-portid" : "portid"); 373 return (tlb_type == spitfire ? "upa-portid" : "portid");
374} 374}
375 375
376bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
377 int cpu, unsigned int *thread)
378{
379 const char *mid_prop = get_mid_prop();
380 int this_cpu_id;
381
382 /* On hypervisor based platforms we interrogate the 'reg'
383 * property. On everything else we look for a 'upa-portis',
384 * 'portid', or 'cpuid' property.
385 */
386
387 if (tlb_type == hypervisor) {
388 struct property *prop = of_find_property(cpun, "reg", NULL);
389 u32 *regs;
390
391 if (!prop) {
392 pr_warn("CPU node missing reg property\n");
393 return false;
394 }
395 regs = prop->value;
396 this_cpu_id = regs[0] & 0x0fffffff;
397 } else {
398 this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
399
400 if (this_cpu_id < 0) {
401 mid_prop = "cpuid";
402 this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
403 }
404 if (this_cpu_id < 0) {
405 pr_warn("CPU node missing cpu ID property\n");
406 return false;
407 }
408 }
409 if (this_cpu_id == cpu) {
410 if (thread) {
411 int proc_id = cpu_data(cpu).proc_id;
412
413 /* On sparc64, the cpu thread information is obtained
414 * either from OBP or the machine description. We've
415 * actually probed this information already long before
416 * this interface gets called so instead of interrogating
417 * both the OF node and the MDESC again, just use what
418 * we discovered already.
419 */
420 if (proc_id < 0)
421 proc_id = 0;
422 *thread = proc_id;
423 }
424 return true;
425 }
426 return false;
427}
428
376static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg) 429static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
377{ 430{
378 struct device_node *dp; 431 struct device_node *dp;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 7d4c70f859e3..e4c99453adf1 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -280,6 +280,31 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
280 return false; 280 return false;
281} 281}
282 282
283/*
284 * arch_find_n_match_cpu_physical_id - See if the given device node is
285 * for the cpu corresponding to logical cpu 'cpu'. Return true if so,
286 * else false. If 'thread' is non-NULL, the local thread number within the
287 * core is returned in it.
288 */
289bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
290 int cpu, unsigned int *thread)
291{
292 /* Check for non-standard "ibm,ppc-interrupt-server#s" property
293 * for thread ids on PowerPC. If it doesn't exist fallback to
294 * standard "reg" property.
295 */
296 if (IS_ENABLED(CONFIG_PPC) &&
297 __of_find_n_match_cpu_property(cpun,
298 "ibm,ppc-interrupt-server#s",
299 cpu, thread))
300 return true;
301
302 if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
303 return true;
304
305 return false;
306}
307
283/** 308/**
284 * of_get_cpu_node - Get device node associated with the given logical CPU 309 * of_get_cpu_node - Get device node associated with the given logical CPU
285 * 310 *
@@ -300,24 +325,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun,
300 */ 325 */
301struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 326struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
302{ 327{
303 struct device_node *cpun, *cpus; 328 struct device_node *cpun;
304
305 cpus = of_find_node_by_path("/cpus");
306 if (!cpus)
307 return NULL;
308 329
309 for_each_child_of_node(cpus, cpun) { 330 for_each_node_by_type(cpun, "cpu") {
310 if (of_node_cmp(cpun->type, "cpu")) 331 if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
311 continue;
312 /* Check for non-standard "ibm,ppc-interrupt-server#s" property
313 * for thread ids on PowerPC. If it doesn't exist fallback to
314 * standard "reg" property.
315 */
316 if (IS_ENABLED(CONFIG_PPC) &&
317 __of_find_n_match_cpu_property(cpun,
318 "ibm,ppc-interrupt-server#s", cpu, thread))
319 return cpun;
320 if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
321 return cpun; 332 return cpun;
322 } 333 }
323 return NULL; 334 return NULL;
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 801ff9e73679..fbd25c3c2923 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -18,6 +18,7 @@
18#include <linux/cpumask.h> 18#include <linux/cpumask.h>
19 19
20struct device; 20struct device;
21struct device_node;
21 22
22struct cpu { 23struct cpu {
23 int node_id; /* The node which contains the CPU */ 24 int node_id; /* The node which contains the CPU */
@@ -29,6 +30,8 @@ extern int register_cpu(struct cpu *cpu, int num);
29extern struct device *get_cpu_device(unsigned cpu); 30extern struct device *get_cpu_device(unsigned cpu);
30extern bool cpu_is_hotpluggable(unsigned cpu); 31extern bool cpu_is_hotpluggable(unsigned cpu);
31extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id); 32extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
33extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
34 int cpu, unsigned int *thread);
32 35
33extern int cpu_add_dev_attr(struct device_attribute *attr); 36extern int cpu_add_dev_attr(struct device_attribute *attr);
34extern void cpu_remove_dev_attr(struct device_attribute *attr); 37extern void cpu_remove_dev_attr(struct device_attribute *attr);