diff options
Diffstat (limited to 'arch/sparc64/kernel/smp.c')
-rw-r--r-- | arch/sparc64/kernel/smp.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 40e40f968d61..315eef0869bd 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/sections.h> | 41 | #include <asm/sections.h> |
42 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
43 | #include <asm/mdesc.h> | 43 | #include <asm/mdesc.h> |
44 | #include <asm/ldc.h> | ||
44 | 45 | ||
45 | extern void calibrate_delay(void); | 46 | extern void calibrate_delay(void); |
46 | 47 | ||
@@ -49,12 +50,18 @@ int sparc64_multi_core __read_mostly; | |||
49 | /* Please don't make this stuff initdata!!! --DaveM */ | 50 | /* Please don't make this stuff initdata!!! --DaveM */ |
50 | unsigned char boot_cpu_id; | 51 | unsigned char boot_cpu_id; |
51 | 52 | ||
53 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; | ||
52 | cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; | 54 | cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; |
53 | cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; | ||
54 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = | 55 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = |
55 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 56 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
56 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = | 57 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = |
57 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 58 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
59 | |||
60 | EXPORT_SYMBOL(cpu_possible_map); | ||
61 | EXPORT_SYMBOL(cpu_online_map); | ||
62 | EXPORT_SYMBOL(cpu_sibling_map); | ||
63 | EXPORT_SYMBOL(cpu_core_map); | ||
64 | |||
58 | static cpumask_t smp_commenced_mask; | 65 | static cpumask_t smp_commenced_mask; |
59 | static cpumask_t cpu_callout_map; | 66 | static cpumask_t cpu_callout_map; |
60 | 67 | ||
@@ -84,9 +91,10 @@ extern void setup_sparc64_timer(void); | |||
84 | 91 | ||
85 | static volatile unsigned long callin_flag = 0; | 92 | static volatile unsigned long callin_flag = 0; |
86 | 93 | ||
87 | void __init smp_callin(void) | 94 | void __devinit smp_callin(void) |
88 | { | 95 | { |
89 | int cpuid = hard_smp_processor_id(); | 96 | int cpuid = hard_smp_processor_id(); |
97 | struct trap_per_cpu *tb = &trap_block[cpuid];; | ||
90 | 98 | ||
91 | __local_per_cpu_offset = __per_cpu_offset(cpuid); | 99 | __local_per_cpu_offset = __per_cpu_offset(cpuid); |
92 | 100 | ||
@@ -117,6 +125,11 @@ void __init smp_callin(void) | |||
117 | atomic_inc(&init_mm.mm_count); | 125 | atomic_inc(&init_mm.mm_count); |
118 | current->active_mm = &init_mm; | 126 | current->active_mm = &init_mm; |
119 | 127 | ||
128 | if (tb->hdesc) { | ||
129 | kfree(tb->hdesc); | ||
130 | tb->hdesc = NULL; | ||
131 | } | ||
132 | |||
120 | while (!cpu_isset(cpuid, smp_commenced_mask)) | 133 | while (!cpu_isset(cpuid, smp_commenced_mask)) |
121 | rmb(); | 134 | rmb(); |
122 | 135 | ||
@@ -296,14 +309,20 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) | |||
296 | /* Alloc the mondo queues, cpu will load them. */ | 309 | /* Alloc the mondo queues, cpu will load them. */ |
297 | sun4v_init_mondo_queues(0, cpu, 1, 0); | 310 | sun4v_init_mondo_queues(0, cpu, 1, 0); |
298 | 311 | ||
299 | prom_startcpu_cpuid(cpu, entry, cookie); | 312 | #ifdef CONFIG_SUN_LDOMS |
313 | if (ldom_domaining_enabled) | ||
314 | ldom_startcpu_cpuid(cpu, | ||
315 | (unsigned long) cpu_new_thread); | ||
316 | else | ||
317 | #endif | ||
318 | prom_startcpu_cpuid(cpu, entry, cookie); | ||
300 | } else { | 319 | } else { |
301 | struct device_node *dp = of_find_node_by_cpuid(cpu); | 320 | struct device_node *dp = of_find_node_by_cpuid(cpu); |
302 | 321 | ||
303 | prom_startcpu(dp->node, entry, cookie); | 322 | prom_startcpu(dp->node, entry, cookie); |
304 | } | 323 | } |
305 | 324 | ||
306 | for (timeout = 0; timeout < 5000000; timeout++) { | 325 | for (timeout = 0; timeout < 50000; timeout++) { |
307 | if (callin_flag) | 326 | if (callin_flag) |
308 | break; | 327 | break; |
309 | udelay(100); | 328 | udelay(100); |
@@ -1163,22 +1182,8 @@ int setup_profiling_timer(unsigned int multiplier) | |||
1163 | return -EINVAL; | 1182 | return -EINVAL; |
1164 | } | 1183 | } |
1165 | 1184 | ||
1166 | /* Constrain the number of cpus to max_cpus. */ | ||
1167 | void __init smp_prepare_cpus(unsigned int max_cpus) | 1185 | void __init smp_prepare_cpus(unsigned int max_cpus) |
1168 | { | 1186 | { |
1169 | int i; | ||
1170 | |||
1171 | if (num_possible_cpus() > max_cpus) { | ||
1172 | for_each_possible_cpu(i) { | ||
1173 | if (i != boot_cpu_id) { | ||
1174 | cpu_clear(i, phys_cpu_present_map); | ||
1175 | cpu_clear(i, cpu_present_map); | ||
1176 | if (num_possible_cpus() <= max_cpus) | ||
1177 | break; | ||
1178 | } | ||
1179 | } | ||
1180 | } | ||
1181 | |||
1182 | cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; | 1187 | cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; |
1183 | } | 1188 | } |
1184 | 1189 | ||
@@ -1242,6 +1247,20 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1242 | return ret; | 1247 | return ret; |
1243 | } | 1248 | } |
1244 | 1249 | ||
1250 | #ifdef CONFIG_HOTPLUG_CPU | ||
1251 | int __cpu_disable(void) | ||
1252 | { | ||
1253 | printk(KERN_ERR "SMP: __cpu_disable() on cpu %d\n", | ||
1254 | smp_processor_id()); | ||
1255 | return -ENODEV; | ||
1256 | } | ||
1257 | |||
1258 | void __cpu_die(unsigned int cpu) | ||
1259 | { | ||
1260 | printk(KERN_ERR "SMP: __cpu_die(%u)\n", cpu); | ||
1261 | } | ||
1262 | #endif | ||
1263 | |||
1245 | void __init smp_cpus_done(unsigned int max_cpus) | 1264 | void __init smp_cpus_done(unsigned int max_cpus) |
1246 | { | 1265 | { |
1247 | unsigned long bogosum = 0; | 1266 | unsigned long bogosum = 0; |