diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-01-06 19:30:44 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 23:47:16 -0500 |
commit | 730745a5c45093982112ddc94cee6a9973455641 (patch) | |
tree | 1c36bd96c28d08e2b5d839ba3f4e37588aad2328 /arch/powerpc/platforms/powermac/smp.c | |
parent | 002ec58eb57bac2380f0ed5a4e88121b4bdb32ec (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.c | 75 |
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 | */ |
485 | static struct device_node *pmac_tb_clock_chip_host; | 485 | static struct pmac_i2c_bus *pmac_tb_clock_chip_host; |
486 | static u8 pmac_tb_pulsar_addr; | 486 | static u8 pmac_tb_pulsar_addr; |
487 | 487 | ||
488 | static void smp_core99_cypress_tb_freeze(int freeze) | 488 | static 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 | ||