Commit 9bab5414 authored by David S. Miller's avatar David S. Miller

sparc64: Refactor OBP cpu scanning code using an iterator.

With feedback from Sam Ravnborg.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 82497789
...@@ -86,6 +86,7 @@ extern int of_node_to_nid(struct device_node *dp); ...@@ -86,6 +86,7 @@ extern int of_node_to_nid(struct device_node *dp);
#endif #endif
extern void prom_build_devicetree(void); extern void prom_build_devicetree(void);
extern void of_populate_present_mask(void);
/* Dummy ref counting routines - to be implemented later */ /* Dummy ref counting routines - to be implemented later */
static inline struct device_node *of_node_get(struct device_node *node) static inline struct device_node *of_node_get(struct device_node *node)
......
...@@ -374,52 +374,78 @@ static const char *get_mid_prop(void) ...@@ -374,52 +374,78 @@ static const char *get_mid_prop(void)
return (tlb_type == spitfire ? "upa-portid" : "portid"); return (tlb_type == spitfire ? "upa-portid" : "portid");
} }
struct device_node *of_find_node_by_cpuid(int cpuid) static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
{ {
struct device_node *dp; struct device_node *dp;
const char *mid_prop = get_mid_prop(); const char *mid_prop;
mid_prop = get_mid_prop();
for_each_node_by_type(dp, "cpu") { for_each_node_by_type(dp, "cpu") {
int id = of_getintprop_default(dp, mid_prop, -1); int cpuid = of_getintprop_default(dp, mid_prop, -1);
const char *this_mid_prop = mid_prop; const char *this_mid_prop = mid_prop;
void *ret;
if (id < 0) { if (cpuid < 0) {
this_mid_prop = "cpuid"; this_mid_prop = "cpuid";
id = of_getintprop_default(dp, this_mid_prop, -1); cpuid = of_getintprop_default(dp, this_mid_prop, -1);
} }
if (cpuid < 0) {
if (id < 0) {
prom_printf("OF: Serious problem, cpu lacks " prom_printf("OF: Serious problem, cpu lacks "
"%s property", this_mid_prop); "%s property", this_mid_prop);
prom_halt(); prom_halt();
} }
if (cpuid == id) #ifdef CONFIG_SMP
return dp; if (cpuid >= NR_CPUS) {
printk(KERN_WARNING "Ignoring CPU %d which is "
">= NR_CPUS (%d)\n",
cpuid, NR_CPUS);
continue;
}
#endif
ret = func(dp, cpuid, arg);
if (ret)
return ret;
} }
return NULL; return NULL;
} }
void __init of_fill_in_cpu_data(void) static void *check_cpu_node(struct device_node *dp, int cpuid, int id)
{ {
struct device_node *dp; if (id == cpuid)
const char *mid_prop; return dp;
return NULL;
}
struct device_node *of_find_node_by_cpuid(int cpuid)
{
return of_iterate_over_cpus(check_cpu_node, cpuid);
}
static void *record_one_cpu(struct device_node *dp, int cpuid, int arg)
{
ncpus_probed++;
#ifdef CONFIG_SMP
set_cpu_present(cpuid, true);
set_cpu_possible(cpuid, true);
#endif
return NULL;
}
void __init of_populate_present_mask(void)
{
if (tlb_type == hypervisor) if (tlb_type == hypervisor)
return; return;
mid_prop = get_mid_prop();
ncpus_probed = 0; ncpus_probed = 0;
for_each_node_by_type(dp, "cpu") { of_iterate_over_cpus(record_one_cpu, 0);
int cpuid = of_getintprop_default(dp, mid_prop, -1); }
const char *this_mid_prop = mid_prop;
struct device_node *portid_parent; static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg)
{
struct device_node *portid_parent = NULL;
int portid = -1; int portid = -1;
portid_parent = NULL; if (of_find_property(dp, "cpuid", NULL)) {
if (cpuid < 0) {
this_mid_prop = "cpuid";
cpuid = of_getintprop_default(dp, this_mid_prop, -1);
if (cpuid >= 0) {
int limit = 2; int limit = 2;
portid_parent = dp; portid_parent = dp;
...@@ -433,30 +459,14 @@ void __init of_fill_in_cpu_data(void) ...@@ -433,30 +459,14 @@ void __init of_fill_in_cpu_data(void)
break; break;
} }
} }
}
if (cpuid < 0) { #ifndef CONFIG_SMP
prom_printf("OF: Serious problem, cpu lacks "
"%s property", this_mid_prop);
prom_halt();
}
ncpus_probed++;
#ifdef CONFIG_SMP
if (cpuid >= NR_CPUS) {
printk(KERN_WARNING "Ignoring CPU %d which is "
">= NR_CPUS (%d)\n",
cpuid, NR_CPUS);
continue;
}
#else
/* On uniprocessor we only want the values for the /* On uniprocessor we only want the values for the
* real physical cpu the kernel booted onto, however * real physical cpu the kernel booted onto, however
* cpu_data() only has one entry at index 0. * cpu_data() only has one entry at index 0.
*/ */
if (cpuid != real_hard_smp_processor_id()) if (cpuid != real_hard_smp_processor_id())
continue; return NULL;
cpuid = 0; cpuid = 0;
#endif #endif
...@@ -517,11 +527,16 @@ void __init of_fill_in_cpu_data(void) ...@@ -517,11 +527,16 @@ void __init of_fill_in_cpu_data(void)
cpu_data(cpuid).proc_id = -1; cpu_data(cpuid).proc_id = -1;
} }
#ifdef CONFIG_SMP return NULL;
set_cpu_present(cpuid, true); }
set_cpu_possible(cpuid, true);
#endif void __init of_fill_in_cpu_data(void)
} {
if (tlb_type == hypervisor)
return;
of_populate_present_mask();
of_iterate_over_cpus(fill_in_one_cpu, 0);
smp_fill_in_sib_core_maps(); smp_fill_in_sib_core_maps();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment