aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/smp.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-01-06 19:30:44 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:47:16 -0500
commit730745a5c45093982112ddc94cee6a9973455641 (patch)
tree1c36bd96c28d08e2b5d839ba3f4e37588aad2328 /arch/powerpc/platforms/powermac/smp.c
parent002ec58eb57bac2380f0ed5a4e88121b4bdb32ec (diff)
[PATCH] 1/5 powerpc: Rework PowerMac i2c part 1
This is the first part of a rework of the PowerMac i2c code. It completely reworks the "low_i2c" layer. It is now more flexible, supports KeyWest, SMU and PMU i2c busses, and provides functions to match device nodes to i2c busses and adapters. This patch also extends & fix some bugs in the SMU driver related to i2c support and removes the clock spreading hacks from the pmac feature code rather than adapting them to the new API since they'll be replaced by the platform function code completely in patch 3/5 Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac/smp.c')
-rw-r--r--arch/powerpc/platforms/powermac/smp.c75
1 files changed, 38 insertions, 37 deletions
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index df01bb8feb1..ab72ba86be1 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -482,7 +482,7 @@ static void __devinit smp_core99_take_timebase(void)
482/* 482/*
483 * G5s enable/disable the timebase via an i2c-connected clock chip. 483 * G5s enable/disable the timebase via an i2c-connected clock chip.
484 */ 484 */
485static struct device_node *pmac_tb_clock_chip_host; 485static struct pmac_i2c_bus *pmac_tb_clock_chip_host;
486static u8 pmac_tb_pulsar_addr; 486static u8 pmac_tb_pulsar_addr;
487 487
488static void smp_core99_cypress_tb_freeze(int freeze) 488static void smp_core99_cypress_tb_freeze(int freeze)
@@ -493,20 +493,20 @@ static void smp_core99_cypress_tb_freeze(int freeze)
493 /* Strangely, the device-tree says address is 0xd2, but darwin 493 /* Strangely, the device-tree says address is 0xd2, but darwin
494 * accesses 0xd0 ... 494 * accesses 0xd0 ...
495 */ 495 */
496 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, 496 pmac_i2c_setmode(pmac_tb_clock_chip_host,
497 pmac_low_i2c_mode_combined); 497 pmac_i2c_mode_combined);
498 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 498 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
499 0xd0 | pmac_low_i2c_read, 499 0xd0 | pmac_i2c_read,
500 0x81, &data, 1); 500 1, 0x81, &data, 1);
501 if (rc != 0) 501 if (rc != 0)
502 goto bail; 502 goto bail;
503 503
504 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c); 504 data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
505 505
506 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); 506 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
507 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 507 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
508 0xd0 | pmac_low_i2c_write, 508 0xd0 | pmac_i2c_write,
509 0x81, &data, 1); 509 1, 0x81, &data, 1);
510 510
511 bail: 511 bail:
512 if (rc != 0) { 512 if (rc != 0) {
@@ -522,20 +522,20 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
522 u8 data; 522 u8 data;
523 int rc; 523 int rc;
524 524
525 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, 525 pmac_i2c_setmode(pmac_tb_clock_chip_host,
526 pmac_low_i2c_mode_combined); 526 pmac_i2c_mode_combined);
527 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 527 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
528 pmac_tb_pulsar_addr | pmac_low_i2c_read, 528 pmac_tb_pulsar_addr | pmac_i2c_read,
529 0x2e, &data, 1); 529 1, 0x2e, &data, 1);
530 if (rc != 0) 530 if (rc != 0)
531 goto bail; 531 goto bail;
532 532
533 data = (data & 0x88) | (freeze ? 0x11 : 0x22); 533 data = (data & 0x88) | (freeze ? 0x11 : 0x22);
534 534
535 pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); 535 pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
536 rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, 536 rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
537 pmac_tb_pulsar_addr | pmac_low_i2c_write, 537 pmac_tb_pulsar_addr | pmac_i2c_write,
538 0x2e, &data, 1); 538 1, 0x2e, &data, 1);
539 bail: 539 bail:
540 if (rc != 0) { 540 if (rc != 0) {
541 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n", 541 printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
@@ -560,13 +560,15 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
560 if (!ok) 560 if (!ok)
561 continue; 561 continue;
562 562
563 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
564 if (pmac_tb_clock_chip_host == NULL)
565 continue;
563 reg = (u32 *)get_property(cc, "reg", NULL); 566 reg = (u32 *)get_property(cc, "reg", NULL);
564 if (reg == NULL) 567 if (reg == NULL)
565 continue; 568 continue;
566
567 switch (*reg) { 569 switch (*reg) {
568 case 0xd2: 570 case 0xd2:
569 if (device_is_compatible(cc, "pulsar-legacy-slewing")) { 571 if (device_is_compatible(cc,"pulsar-legacy-slewing")) {
570 pmac_tb_freeze = smp_core99_pulsar_tb_freeze; 572 pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
571 pmac_tb_pulsar_addr = 0xd2; 573 pmac_tb_pulsar_addr = 0xd2;
572 name = "Pulsar"; 574 name = "Pulsar";
@@ -585,30 +587,19 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
585 break; 587 break;
586 } 588 }
587 if (pmac_tb_freeze != NULL) { 589 if (pmac_tb_freeze != NULL) {
588 struct device_node *p = of_get_parent(cc);
589 of_node_put(cc);
590 while(p && strcmp(p->type, "i2c")) {
591 cc = of_get_parent(p);
592 of_node_put(p);
593 p = cc;
594 }
595 if (p == NULL)
596 goto no_i2c_sync;
597 /* Open i2c bus for synchronous access */ 590 /* Open i2c bus for synchronous access */
598 if (pmac_low_i2c_open(p, 0)) { 591 if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) {
599 printk(KERN_ERR "Failed top open i2c bus %s for clock" 592 printk(KERN_ERR "Failed top open i2c bus for clock"
600 " sync, fallback to software sync !\n", 593 " sync, fallback to software sync !\n");
601 p->full_name);
602 of_node_put(p);
603 goto no_i2c_sync; 594 goto no_i2c_sync;
604 } 595 }
605 pmac_tb_clock_chip_host = p;
606 printk(KERN_INFO "Processor timebase sync using %s i2c clock\n", 596 printk(KERN_INFO "Processor timebase sync using %s i2c clock\n",
607 name); 597 name);
608 return; 598 return;
609 } 599 }
610 no_i2c_sync: 600 no_i2c_sync:
611 pmac_tb_freeze = NULL; 601 pmac_tb_freeze = NULL;
602 pmac_tb_clock_chip_host = NULL;
612} 603}
613 604
614#endif /* CONFIG_PPC64 */ 605#endif /* CONFIG_PPC64 */
@@ -752,8 +743,18 @@ static int __init smp_core99_probe(void)
752 if (ncpus <= 1) 743 if (ncpus <= 1)
753 return 1; 744 return 1;
754 745
746 /* We need to perform some early initialisations before we can start
747 * setting up SMP as we are running before initcalls
748 */
749 pmac_i2c_init();
750
751 /* Setup various bits like timebase sync method, ability to nap, ... */
755 smp_core99_setup(ncpus); 752 smp_core99_setup(ncpus);
753
754 /* Install IPIs */
756 mpic_request_ipis(); 755 mpic_request_ipis();
756
757 /* Collect l2cr and l3cr values from CPU 0 */
757 core99_init_caches(0); 758 core99_init_caches(0);
758 759
759 return ncpus; 760 return ncpus;
@@ -817,7 +818,7 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
817 818
818 /* Close i2c bus if it was used for tb sync */ 819 /* Close i2c bus if it was used for tb sync */
819 if (pmac_tb_clock_chip_host) { 820 if (pmac_tb_clock_chip_host) {
820 pmac_low_i2c_close(pmac_tb_clock_chip_host); 821 pmac_i2c_close(pmac_tb_clock_chip_host);
821 pmac_tb_clock_chip_host = NULL; 822 pmac_tb_clock_chip_host = NULL;
822 } 823 }
823 824