diff options
Diffstat (limited to 'arch/powerpc/kernel/setup-common.c')
-rw-r--r-- | arch/powerpc/kernel/setup-common.c | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index fc89d009d18d..1d93e73a7003 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -9,6 +9,9 @@ | |||
9 | * as published by the Free Software Foundation; either version | 9 | * as published by the Free Software Foundation; either version |
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | */ | 11 | */ |
12 | |||
13 | #undef DEBUG | ||
14 | |||
12 | #include <linux/config.h> | 15 | #include <linux/config.h> |
13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
14 | #include <linux/string.h> | 17 | #include <linux/string.h> |
@@ -42,6 +45,7 @@ | |||
42 | #include <asm/time.h> | 45 | #include <asm/time.h> |
43 | #include <asm/cputable.h> | 46 | #include <asm/cputable.h> |
44 | #include <asm/sections.h> | 47 | #include <asm/sections.h> |
48 | #include <asm/firmware.h> | ||
45 | #include <asm/btext.h> | 49 | #include <asm/btext.h> |
46 | #include <asm/nvram.h> | 50 | #include <asm/nvram.h> |
47 | #include <asm/setup.h> | 51 | #include <asm/setup.h> |
@@ -57,8 +61,6 @@ | |||
57 | 61 | ||
58 | #include "setup.h" | 62 | #include "setup.h" |
59 | 63 | ||
60 | #undef DEBUG | ||
61 | |||
62 | #ifdef DEBUG | 64 | #ifdef DEBUG |
63 | #include <asm/udbg.h> | 65 | #include <asm/udbg.h> |
64 | #define DBG(fmt...) udbg_printf(fmt) | 66 | #define DBG(fmt...) udbg_printf(fmt) |
@@ -66,10 +68,12 @@ | |||
66 | #define DBG(fmt...) | 68 | #define DBG(fmt...) |
67 | #endif | 69 | #endif |
68 | 70 | ||
69 | #ifdef CONFIG_PPC_MULTIPLATFORM | 71 | /* The main machine-dep calls structure |
70 | int _machine = 0; | 72 | */ |
71 | EXPORT_SYMBOL(_machine); | 73 | struct machdep_calls ppc_md; |
72 | #endif | 74 | EXPORT_SYMBOL(ppc_md); |
75 | struct machdep_calls *machine_id; | ||
76 | EXPORT_SYMBOL(machine_id); | ||
73 | 77 | ||
74 | unsigned long klimit = (unsigned long) _end; | 78 | unsigned long klimit = (unsigned long) _end; |
75 | 79 | ||
@@ -163,14 +167,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
163 | #if defined(CONFIG_SMP) && defined(CONFIG_PPC32) | 167 | #if defined(CONFIG_SMP) && defined(CONFIG_PPC32) |
164 | unsigned long bogosum = 0; | 168 | unsigned long bogosum = 0; |
165 | int i; | 169 | int i; |
166 | for (i = 0; i < NR_CPUS; ++i) | 170 | for_each_online_cpu(i) |
167 | if (cpu_online(i)) | 171 | bogosum += loops_per_jiffy; |
168 | bogosum += loops_per_jiffy; | ||
169 | seq_printf(m, "total bogomips\t: %lu.%02lu\n", | 172 | seq_printf(m, "total bogomips\t: %lu.%02lu\n", |
170 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); | 173 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); |
171 | #endif /* CONFIG_SMP && CONFIG_PPC32 */ | 174 | #endif /* CONFIG_SMP && CONFIG_PPC32 */ |
172 | seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); | 175 | seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); |
173 | 176 | if (ppc_md.name) | |
177 | seq_printf(m, "platform\t: %s\n", ppc_md.name); | ||
174 | if (ppc_md.show_cpuinfo != NULL) | 178 | if (ppc_md.show_cpuinfo != NULL) |
175 | ppc_md.show_cpuinfo(m); | 179 | ppc_md.show_cpuinfo(m); |
176 | 180 | ||
@@ -354,12 +358,13 @@ void __init check_for_initrd(void) | |||
354 | * must be called before using this. | 358 | * must be called before using this. |
355 | * | 359 | * |
356 | * While we're here, we may as well set the "physical" cpu ids in the paca. | 360 | * While we're here, we may as well set the "physical" cpu ids in the paca. |
361 | * | ||
362 | * NOTE: This must match the parsing done in early_init_dt_scan_cpus. | ||
357 | */ | 363 | */ |
358 | void __init smp_setup_cpu_maps(void) | 364 | void __init smp_setup_cpu_maps(void) |
359 | { | 365 | { |
360 | struct device_node *dn = NULL; | 366 | struct device_node *dn = NULL; |
361 | int cpu = 0; | 367 | int cpu = 0; |
362 | int swap_cpuid = 0; | ||
363 | 368 | ||
364 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { | 369 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { |
365 | int *intserv; | 370 | int *intserv; |
@@ -378,30 +383,17 @@ void __init smp_setup_cpu_maps(void) | |||
378 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { | 383 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { |
379 | cpu_set(cpu, cpu_present_map); | 384 | cpu_set(cpu, cpu_present_map); |
380 | set_hard_smp_processor_id(cpu, intserv[j]); | 385 | set_hard_smp_processor_id(cpu, intserv[j]); |
381 | |||
382 | if (intserv[j] == boot_cpuid_phys) | ||
383 | swap_cpuid = cpu; | ||
384 | cpu_set(cpu, cpu_possible_map); | 386 | cpu_set(cpu, cpu_possible_map); |
385 | cpu++; | 387 | cpu++; |
386 | } | 388 | } |
387 | } | 389 | } |
388 | 390 | ||
389 | /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that | ||
390 | * boot cpu is logical 0. | ||
391 | */ | ||
392 | if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { | ||
393 | u32 tmp; | ||
394 | tmp = get_hard_smp_processor_id(0); | ||
395 | set_hard_smp_processor_id(0, boot_cpuid_phys); | ||
396 | set_hard_smp_processor_id(swap_cpuid, tmp); | ||
397 | } | ||
398 | |||
399 | #ifdef CONFIG_PPC64 | 391 | #ifdef CONFIG_PPC64 |
400 | /* | 392 | /* |
401 | * On pSeries LPAR, we need to know how many cpus | 393 | * On pSeries LPAR, we need to know how many cpus |
402 | * could possibly be added to this partition. | 394 | * could possibly be added to this partition. |
403 | */ | 395 | */ |
404 | if (_machine == PLATFORM_PSERIES_LPAR && | 396 | if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && |
405 | (dn = of_find_node_by_path("/rtas"))) { | 397 | (dn = of_find_node_by_path("/rtas"))) { |
406 | int num_addr_cell, num_size_cell, maxcpus; | 398 | int num_addr_cell, num_size_cell, maxcpus; |
407 | unsigned int *ireg; | 399 | unsigned int *ireg; |
@@ -440,7 +432,7 @@ void __init smp_setup_cpu_maps(void) | |||
440 | /* | 432 | /* |
441 | * Do the sibling map; assume only two threads per processor. | 433 | * Do the sibling map; assume only two threads per processor. |
442 | */ | 434 | */ |
443 | for_each_cpu(cpu) { | 435 | for_each_possible_cpu(cpu) { |
444 | cpu_set(cpu, cpu_sibling_map[cpu]); | 436 | cpu_set(cpu, cpu_sibling_map[cpu]); |
445 | if (cpu_has_feature(CPU_FTR_SMT)) | 437 | if (cpu_has_feature(CPU_FTR_SMT)) |
446 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); | 438 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); |
@@ -493,3 +485,34 @@ static __init int add_pcspkr(void) | |||
493 | return ret; | 485 | return ret; |
494 | } | 486 | } |
495 | device_initcall(add_pcspkr); | 487 | device_initcall(add_pcspkr); |
488 | |||
489 | void probe_machine(void) | ||
490 | { | ||
491 | extern struct machdep_calls __machine_desc_start; | ||
492 | extern struct machdep_calls __machine_desc_end; | ||
493 | |||
494 | /* | ||
495 | * Iterate all ppc_md structures until we find the proper | ||
496 | * one for the current machine type | ||
497 | */ | ||
498 | DBG("Probing machine type ...\n"); | ||
499 | |||
500 | for (machine_id = &__machine_desc_start; | ||
501 | machine_id < &__machine_desc_end; | ||
502 | machine_id++) { | ||
503 | DBG(" %s ...", machine_id->name); | ||
504 | memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls)); | ||
505 | if (ppc_md.probe()) { | ||
506 | DBG(" match !\n"); | ||
507 | break; | ||
508 | } | ||
509 | DBG("\n"); | ||
510 | } | ||
511 | /* What can we do if we didn't find ? */ | ||
512 | if (machine_id >= &__machine_desc_end) { | ||
513 | DBG("No suitable machine found !\n"); | ||
514 | for (;;); | ||
515 | } | ||
516 | |||
517 | printk(KERN_INFO "Using %s machine description\n", ppc_md.name); | ||
518 | } | ||