diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:37:24 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:37:24 -0500 |
| commit | d40d9d29c020f8466c96f8e3ad4b7c014ff1085d (patch) | |
| tree | cb30b4e80f37e0d734a826aa6b29394f46123f9f /arch/powerpc/kernel/setup-common.c | |
| parent | 96a71d52bb91d9b386a60f904956420f98946dd3 (diff) | |
| parent | 70d9d825e0a5a78ec1dacaaaf5c72ff5b0206fab (diff) | |
Merge branch 'master'
Diffstat (limited to 'arch/powerpc/kernel/setup-common.c')
| -rw-r--r-- | arch/powerpc/kernel/setup-common.c | 123 |
1 files changed, 117 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 1292460fcde2..d43fa8c0e5ac 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
| @@ -170,12 +170,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | #ifdef CONFIG_SMP | 172 | #ifdef CONFIG_SMP |
| 173 | #ifdef CONFIG_PPC64 /* XXX for now */ | ||
| 174 | pvr = per_cpu(pvr, cpu_id); | 173 | pvr = per_cpu(pvr, cpu_id); |
| 175 | #else | 174 | #else |
| 176 | pvr = cpu_data[cpu_id].pvr; | ||
| 177 | #endif | ||
| 178 | #else | ||
| 179 | pvr = mfspr(SPRN_PVR); | 175 | pvr = mfspr(SPRN_PVR); |
| 180 | #endif | 176 | #endif |
| 181 | maj = (pvr >> 8) & 0xFF; | 177 | maj = (pvr >> 8) & 0xFF; |
| @@ -201,11 +197,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
| 201 | #ifdef CONFIG_TAU_AVERAGE | 197 | #ifdef CONFIG_TAU_AVERAGE |
| 202 | /* more straightforward, but potentially misleading */ | 198 | /* more straightforward, but potentially misleading */ |
| 203 | seq_printf(m, "temperature \t: %u C (uncalibrated)\n", | 199 | seq_printf(m, "temperature \t: %u C (uncalibrated)\n", |
| 204 | cpu_temp(i)); | 200 | cpu_temp(cpu_id)); |
| 205 | #else | 201 | #else |
| 206 | /* show the actual temp sensor range */ | 202 | /* show the actual temp sensor range */ |
| 207 | u32 temp; | 203 | u32 temp; |
| 208 | temp = cpu_temp_both(i); | 204 | temp = cpu_temp_both(cpu_id); |
| 209 | seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", | 205 | seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", |
| 210 | temp & 0xff, temp >> 16); | 206 | temp & 0xff, temp >> 16); |
| 211 | #endif | 207 | #endif |
| @@ -408,3 +404,118 @@ static int __init set_preferred_console(void) | |||
| 408 | } | 404 | } |
| 409 | console_initcall(set_preferred_console); | 405 | console_initcall(set_preferred_console); |
| 410 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 406 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
| 407 | |||
| 408 | #ifdef CONFIG_SMP | ||
| 409 | |||
| 410 | /** | ||
| 411 | * setup_cpu_maps - initialize the following cpu maps: | ||
| 412 | * cpu_possible_map | ||
| 413 | * cpu_present_map | ||
| 414 | * cpu_sibling_map | ||
| 415 | * | ||
| 416 | * Having the possible map set up early allows us to restrict allocations | ||
| 417 | * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. | ||
| 418 | * | ||
| 419 | * We do not initialize the online map here; cpus set their own bits in | ||
| 420 | * cpu_online_map as they come up. | ||
| 421 | * | ||
| 422 | * This function is valid only for Open Firmware systems. finish_device_tree | ||
| 423 | * must be called before using this. | ||
| 424 | * | ||
| 425 | * While we're here, we may as well set the "physical" cpu ids in the paca. | ||
| 426 | */ | ||
| 427 | void __init smp_setup_cpu_maps(void) | ||
| 428 | { | ||
| 429 | struct device_node *dn = NULL; | ||
| 430 | int cpu = 0; | ||
| 431 | int swap_cpuid = 0; | ||
| 432 | |||
| 433 | while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { | ||
| 434 | int *intserv; | ||
| 435 | int j, len = sizeof(u32), nthreads = 1; | ||
| 436 | |||
| 437 | intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s", | ||
| 438 | &len); | ||
| 439 | if (intserv) | ||
| 440 | nthreads = len / sizeof(int); | ||
| 441 | else { | ||
| 442 | intserv = (int *) get_property(dn, "reg", NULL); | ||
| 443 | if (!intserv) | ||
| 444 | intserv = &cpu; /* assume logical == phys */ | ||
| 445 | } | ||
| 446 | |||
| 447 | for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { | ||
| 448 | cpu_set(cpu, cpu_present_map); | ||
| 449 | set_hard_smp_processor_id(cpu, intserv[j]); | ||
| 450 | |||
| 451 | if (intserv[j] == boot_cpuid_phys) | ||
| 452 | swap_cpuid = cpu; | ||
| 453 | cpu_set(cpu, cpu_possible_map); | ||
| 454 | cpu++; | ||
| 455 | } | ||
| 456 | } | ||
| 457 | |||
| 458 | /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that | ||
| 459 | * boot cpu is logical 0. | ||
| 460 | */ | ||
| 461 | if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { | ||
| 462 | u32 tmp; | ||
| 463 | tmp = get_hard_smp_processor_id(0); | ||
| 464 | set_hard_smp_processor_id(0, boot_cpuid_phys); | ||
| 465 | set_hard_smp_processor_id(swap_cpuid, tmp); | ||
| 466 | } | ||
| 467 | |||
| 468 | #ifdef CONFIG_PPC64 | ||
| 469 | /* | ||
| 470 | * On pSeries LPAR, we need to know how many cpus | ||
| 471 | * could possibly be added to this partition. | ||
| 472 | */ | ||
| 473 | if (systemcfg->platform == PLATFORM_PSERIES_LPAR && | ||
| 474 | (dn = of_find_node_by_path("/rtas"))) { | ||
| 475 | int num_addr_cell, num_size_cell, maxcpus; | ||
| 476 | unsigned int *ireg; | ||
| 477 | |||
| 478 | num_addr_cell = prom_n_addr_cells(dn); | ||
| 479 | num_size_cell = prom_n_size_cells(dn); | ||
| 480 | |||
| 481 | ireg = (unsigned int *) | ||
| 482 | get_property(dn, "ibm,lrdr-capacity", NULL); | ||
| 483 | |||
| 484 | if (!ireg) | ||
| 485 | goto out; | ||
| 486 | |||
| 487 | maxcpus = ireg[num_addr_cell + num_size_cell]; | ||
| 488 | |||
| 489 | /* Double maxcpus for processors which have SMT capability */ | ||
| 490 | if (cpu_has_feature(CPU_FTR_SMT)) | ||
| 491 | maxcpus *= 2; | ||
| 492 | |||
| 493 | if (maxcpus > NR_CPUS) { | ||
| 494 | printk(KERN_WARNING | ||
| 495 | "Partition configured for %d cpus, " | ||
| 496 | "operating system maximum is %d.\n", | ||
| 497 | maxcpus, NR_CPUS); | ||
| 498 | maxcpus = NR_CPUS; | ||
| 499 | } else | ||
| 500 | printk(KERN_INFO "Partition configured for %d cpus.\n", | ||
| 501 | maxcpus); | ||
| 502 | |||
| 503 | for (cpu = 0; cpu < maxcpus; cpu++) | ||
| 504 | cpu_set(cpu, cpu_possible_map); | ||
| 505 | out: | ||
| 506 | of_node_put(dn); | ||
| 507 | } | ||
| 508 | |||
| 509 | /* | ||
| 510 | * Do the sibling map; assume only two threads per processor. | ||
| 511 | */ | ||
| 512 | for_each_cpu(cpu) { | ||
| 513 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
| 514 | if (cpu_has_feature(CPU_FTR_SMT)) | ||
| 515 | cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); | ||
| 516 | } | ||
| 517 | |||
| 518 | systemcfg->processorCount = num_present_cpus(); | ||
| 519 | #endif /* CONFIG_PPC64 */ | ||
| 520 | } | ||
| 521 | #endif /* CONFIG_SMP */ | ||
