Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sparc64: Refactor OBP cpu scanning code using an iterator.

With feedback from Sam Ravnborg.

Signed-off-by: David S. Miller <davem@davemloft.net>

+123 -107
+1
arch/sparc/include/asm/prom.h
··· 86 86 #endif 87 87 88 88 extern void prom_build_devicetree(void); 89 + extern void of_populate_present_mask(void); 89 90 90 91 /* Dummy ref counting routines - to be implemented later */ 91 92 static inline struct device_node *of_node_get(struct device_node *node)
+122 -107
arch/sparc/kernel/prom_64.c
··· 374 374 return (tlb_type == spitfire ? "upa-portid" : "portid"); 375 375 } 376 376 377 - struct device_node *of_find_node_by_cpuid(int cpuid) 378 - { 379 - struct device_node *dp; 380 - const char *mid_prop = get_mid_prop(); 381 - 382 - for_each_node_by_type(dp, "cpu") { 383 - int id = of_getintprop_default(dp, mid_prop, -1); 384 - const char *this_mid_prop = mid_prop; 385 - 386 - if (id < 0) { 387 - this_mid_prop = "cpuid"; 388 - id = of_getintprop_default(dp, this_mid_prop, -1); 389 - } 390 - 391 - if (id < 0) { 392 - prom_printf("OF: Serious problem, cpu lacks " 393 - "%s property", this_mid_prop); 394 - prom_halt(); 395 - } 396 - if (cpuid == id) 397 - return dp; 398 - } 399 - return NULL; 400 - } 401 - 402 - void __init of_fill_in_cpu_data(void) 377 + static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg) 403 378 { 404 379 struct device_node *dp; 405 380 const char *mid_prop; 406 381 407 - if (tlb_type == hypervisor) 408 - return; 409 - 410 382 mid_prop = get_mid_prop(); 411 - ncpus_probed = 0; 412 383 for_each_node_by_type(dp, "cpu") { 413 384 int cpuid = of_getintprop_default(dp, mid_prop, -1); 414 385 const char *this_mid_prop = mid_prop; 415 - struct device_node *portid_parent; 416 - int portid = -1; 386 + void *ret; 417 387 418 - portid_parent = NULL; 419 388 if (cpuid < 0) { 420 389 this_mid_prop = "cpuid"; 421 390 cpuid = of_getintprop_default(dp, this_mid_prop, -1); 422 - if (cpuid >= 0) { 423 - int limit = 2; 424 - 425 - portid_parent = dp; 426 - while (limit--) { 427 - portid_parent = portid_parent->parent; 428 - if (!portid_parent) 429 - break; 430 - portid = of_getintprop_default(portid_parent, 431 - "portid", -1); 432 - if (portid >= 0) 433 - break; 434 - } 435 - } 436 391 } 437 - 438 392 if (cpuid < 0) { 439 393 prom_printf("OF: Serious problem, cpu lacks " 440 394 "%s property", this_mid_prop); 441 395 prom_halt(); 442 396 } 443 - 444 - ncpus_probed++; 445 - 446 397 #ifdef CONFIG_SMP 447 398 if (cpuid >= NR_CPUS) { 448 399 printk(KERN_WARNING "Ignoring CPU %d which is " ··· 401 450 cpuid, NR_CPUS); 402 451 continue; 403 452 } 404 - #else 405 - /* On uniprocessor we only want the values for the 406 - * real physical cpu the kernel booted onto, however 407 - * cpu_data() only has one entry at index 0. 408 - */ 409 - if (cpuid != real_hard_smp_processor_id()) 410 - continue; 411 - cpuid = 0; 412 453 #endif 454 + ret = func(dp, cpuid, arg); 455 + if (ret) 456 + return ret; 457 + } 458 + return NULL; 459 + } 413 460 414 - cpu_data(cpuid).clock_tick = 415 - of_getintprop_default(dp, "clock-frequency", 0); 461 + static void *check_cpu_node(struct device_node *dp, int cpuid, int id) 462 + { 463 + if (id == cpuid) 464 + return dp; 465 + return NULL; 466 + } 416 467 417 - if (portid_parent) { 418 - cpu_data(cpuid).dcache_size = 419 - of_getintprop_default(dp, "l1-dcache-size", 420 - 16 * 1024); 421 - cpu_data(cpuid).dcache_line_size = 422 - of_getintprop_default(dp, "l1-dcache-line-size", 423 - 32); 424 - cpu_data(cpuid).icache_size = 425 - of_getintprop_default(dp, "l1-icache-size", 426 - 8 * 1024); 427 - cpu_data(cpuid).icache_line_size = 428 - of_getintprop_default(dp, "l1-icache-line-size", 429 - 32); 430 - cpu_data(cpuid).ecache_size = 431 - of_getintprop_default(dp, "l2-cache-size", 0); 432 - cpu_data(cpuid).ecache_line_size = 433 - of_getintprop_default(dp, "l2-cache-line-size", 0); 434 - if (!cpu_data(cpuid).ecache_size || 435 - !cpu_data(cpuid).ecache_line_size) { 436 - cpu_data(cpuid).ecache_size = 437 - of_getintprop_default(portid_parent, 438 - "l2-cache-size", 439 - (4 * 1024 * 1024)); 440 - cpu_data(cpuid).ecache_line_size = 441 - of_getintprop_default(portid_parent, 442 - "l2-cache-line-size", 64); 443 - } 468 + struct device_node *of_find_node_by_cpuid(int cpuid) 469 + { 470 + return of_iterate_over_cpus(check_cpu_node, cpuid); 471 + } 444 472 445 - cpu_data(cpuid).core_id = portid + 1; 446 - cpu_data(cpuid).proc_id = portid; 473 + static void *record_one_cpu(struct device_node *dp, int cpuid, int arg) 474 + { 475 + ncpus_probed++; 447 476 #ifdef CONFIG_SMP 448 - sparc64_multi_core = 1; 477 + set_cpu_present(cpuid, true); 478 + set_cpu_possible(cpuid, true); 449 479 #endif 450 - } else { 451 - cpu_data(cpuid).dcache_size = 452 - of_getintprop_default(dp, "dcache-size", 16 * 1024); 453 - cpu_data(cpuid).dcache_line_size = 454 - of_getintprop_default(dp, "dcache-line-size", 32); 480 + return NULL; 481 + } 455 482 456 - cpu_data(cpuid).icache_size = 457 - of_getintprop_default(dp, "icache-size", 16 * 1024); 458 - cpu_data(cpuid).icache_line_size = 459 - of_getintprop_default(dp, "icache-line-size", 32); 483 + void __init of_populate_present_mask(void) 484 + { 485 + if (tlb_type == hypervisor) 486 + return; 460 487 488 + ncpus_probed = 0; 489 + of_iterate_over_cpus(record_one_cpu, 0); 490 + } 491 + 492 + static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg) 493 + { 494 + struct device_node *portid_parent = NULL; 495 + int portid = -1; 496 + 497 + if (of_find_property(dp, "cpuid", NULL)) { 498 + int limit = 2; 499 + 500 + portid_parent = dp; 501 + while (limit--) { 502 + portid_parent = portid_parent->parent; 503 + if (!portid_parent) 504 + break; 505 + portid = of_getintprop_default(portid_parent, 506 + "portid", -1); 507 + if (portid >= 0) 508 + break; 509 + } 510 + } 511 + 512 + #ifndef CONFIG_SMP 513 + /* On uniprocessor we only want the values for the 514 + * real physical cpu the kernel booted onto, however 515 + * cpu_data() only has one entry at index 0. 516 + */ 517 + if (cpuid != real_hard_smp_processor_id()) 518 + return NULL; 519 + cpuid = 0; 520 + #endif 521 + 522 + cpu_data(cpuid).clock_tick = 523 + of_getintprop_default(dp, "clock-frequency", 0); 524 + 525 + if (portid_parent) { 526 + cpu_data(cpuid).dcache_size = 527 + of_getintprop_default(dp, "l1-dcache-size", 528 + 16 * 1024); 529 + cpu_data(cpuid).dcache_line_size = 530 + of_getintprop_default(dp, "l1-dcache-line-size", 531 + 32); 532 + cpu_data(cpuid).icache_size = 533 + of_getintprop_default(dp, "l1-icache-size", 534 + 8 * 1024); 535 + cpu_data(cpuid).icache_line_size = 536 + of_getintprop_default(dp, "l1-icache-line-size", 537 + 32); 538 + cpu_data(cpuid).ecache_size = 539 + of_getintprop_default(dp, "l2-cache-size", 0); 540 + cpu_data(cpuid).ecache_line_size = 541 + of_getintprop_default(dp, "l2-cache-line-size", 0); 542 + if (!cpu_data(cpuid).ecache_size || 543 + !cpu_data(cpuid).ecache_line_size) { 461 544 cpu_data(cpuid).ecache_size = 462 - of_getintprop_default(dp, "ecache-size", 545 + of_getintprop_default(portid_parent, 546 + "l2-cache-size", 463 547 (4 * 1024 * 1024)); 464 548 cpu_data(cpuid).ecache_line_size = 465 - of_getintprop_default(dp, "ecache-line-size", 64); 466 - 467 - cpu_data(cpuid).core_id = 0; 468 - cpu_data(cpuid).proc_id = -1; 549 + of_getintprop_default(portid_parent, 550 + "l2-cache-line-size", 64); 469 551 } 470 552 553 + cpu_data(cpuid).core_id = portid + 1; 554 + cpu_data(cpuid).proc_id = portid; 471 555 #ifdef CONFIG_SMP 472 - set_cpu_present(cpuid, true); 473 - set_cpu_possible(cpuid, true); 556 + sparc64_multi_core = 1; 474 557 #endif 558 + } else { 559 + cpu_data(cpuid).dcache_size = 560 + of_getintprop_default(dp, "dcache-size", 16 * 1024); 561 + cpu_data(cpuid).dcache_line_size = 562 + of_getintprop_default(dp, "dcache-line-size", 32); 563 + 564 + cpu_data(cpuid).icache_size = 565 + of_getintprop_default(dp, "icache-size", 16 * 1024); 566 + cpu_data(cpuid).icache_line_size = 567 + of_getintprop_default(dp, "icache-line-size", 32); 568 + 569 + cpu_data(cpuid).ecache_size = 570 + of_getintprop_default(dp, "ecache-size", 571 + (4 * 1024 * 1024)); 572 + cpu_data(cpuid).ecache_line_size = 573 + of_getintprop_default(dp, "ecache-line-size", 64); 574 + 575 + cpu_data(cpuid).core_id = 0; 576 + cpu_data(cpuid).proc_id = -1; 475 577 } 578 + 579 + return NULL; 580 + } 581 + 582 + void __init of_fill_in_cpu_data(void) 583 + { 584 + if (tlb_type == hypervisor) 585 + return; 586 + 587 + of_populate_present_mask(); 588 + of_iterate_over_cpus(fill_in_one_cpu, 0); 476 589 477 590 smp_fill_in_sib_core_maps(); 478 591 }