aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r--arch/powerpc/platforms/powermac/Makefile2
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c2
-rw-r--r--arch/powerpc/platforms/powermac/pci.c2
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h1
-rw-r--r--arch/powerpc/platforms/powermac/setup.c56
-rw-r--r--arch/powerpc/platforms/powermac/smp.c154
6 files changed, 111 insertions, 106 deletions
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 50f169392551..ea47df66fee5 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -11,7 +11,7 @@ obj-y += pic.o setup.o time.o feature.o pci.o \
11obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o 11obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
12obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o 12obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
13obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o 13obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
14# CONFIG_NVRAM is an arch. independant tristate symbol, for pmac32 we really 14# CONFIG_NVRAM is an arch. independent tristate symbol, for pmac32 we really
15# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really 15# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really
16# CONFIG_NVRAM=y 16# CONFIG_NVRAM=y
17obj-$(CONFIG_NVRAM:m=y) += nvram.o 17obj-$(CONFIG_NVRAM:m=y) += nvram.o
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 480567e5fa9a..e9c8a607268e 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -904,7 +904,7 @@ static void __init smu_i2c_probe(void)
904 printk(KERN_INFO "SMU i2c %s\n", controller->full_name); 904 printk(KERN_INFO "SMU i2c %s\n", controller->full_name);
905 905
906 /* Look for childs, note that they might not be of the right 906 /* Look for childs, note that they might not be of the right
907 * type as older device trees mix i2c busses and other thigns 907 * type as older device trees mix i2c busses and other things
908 * at the same level 908 * at the same level
909 */ 909 */
910 for (busnode = NULL; 910 for (busnode = NULL;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index ab6898942700..f33e08d573ce 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -299,7 +299,7 @@ static void __init setup_chaos(struct pci_controller *hose,
299 * This function deals with some "special cases" devices. 299 * This function deals with some "special cases" devices.
300 * 300 *
301 * 0 -> No special case 301 * 0 -> No special case
302 * 1 -> Skip the device but act as if the access was successfull 302 * 1 -> Skip the device but act as if the access was successful
303 * (return 0xff's on reads, eventually, cache config space 303 * (return 0xff's on reads, eventually, cache config space
304 * accesses in a later version) 304 * accesses in a later version)
305 * -1 -> Hide the device (unsuccessful access) 305 * -1 -> Hide the device (unsuccessful access)
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index f0bc08f6c1f0..20468f49aec0 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void);
33extern void pmac_check_ht_link(void); 33extern void pmac_check_ht_link(void);
34 34
35extern void pmac_setup_smp(void); 35extern void pmac_setup_smp(void);
36extern void pmac32_cpu_die(void);
37extern void low_cpu_die(void) __attribute__((noreturn)); 36extern void low_cpu_die(void) __attribute__((noreturn));
38 37
39extern int pmac_nvram_init(void); 38extern int pmac_nvram_init(void);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index d5aceb7fb125..aa45281bd296 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
650 return PCI_PROBE_NORMAL; 650 return PCI_PROBE_NORMAL;
651 return PCI_PROBE_DEVTREE; 651 return PCI_PROBE_DEVTREE;
652} 652}
653
654#ifdef CONFIG_HOTPLUG_CPU
655/* access per cpu vars from generic smp.c */
656DECLARE_PER_CPU(int, cpu_state);
657
658static void pmac64_cpu_die(void)
659{
660 /*
661 * turn off as much as possible, we'll be
662 * kicked out as this will only be invoked
663 * on core99 platforms for now ...
664 */
665
666 printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
667 __get_cpu_var(cpu_state) = CPU_DEAD;
668 smp_wmb();
669
670 /*
671 * during the path that leads here preemption is disabled,
672 * reenable it now so that when coming up preempt count is
673 * zero correctly
674 */
675 preempt_enable();
676
677 /*
678 * hard-disable interrupts for the non-NAP case, the NAP code
679 * needs to re-enable interrupts (but soft-disables them)
680 */
681 hard_irq_disable();
682
683 while (1) {
684 /* let's not take timer interrupts too often ... */
685 set_dec(0x7fffffff);
686
687 /* should always be true at this point */
688 if (cpu_has_feature(CPU_FTR_CAN_NAP))
689 power4_cpu_offline_powersave();
690 else {
691 HMT_low();
692 HMT_very_low();
693 }
694 }
695}
696#endif /* CONFIG_HOTPLUG_CPU */
697
698#endif /* CONFIG_PPC64 */ 653#endif /* CONFIG_PPC64 */
699 654
700define_machine(powermac) { 655define_machine(powermac) {
@@ -726,15 +681,4 @@ define_machine(powermac) {
726 .pcibios_after_init = pmac_pcibios_after_init, 681 .pcibios_after_init = pmac_pcibios_after_init,
727 .phys_mem_access_prot = pci_phys_mem_access_prot, 682 .phys_mem_access_prot = pci_phys_mem_access_prot,
728#endif 683#endif
729#ifdef CONFIG_HOTPLUG_CPU
730#ifdef CONFIG_PPC64
731 .cpu_die = pmac64_cpu_die,
732#endif
733#ifdef CONFIG_PPC32
734 .cpu_die = pmac32_cpu_die,
735#endif
736#endif
737#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
738 .cpu_die = generic_mach_cpu_die,
739#endif
740}; 684};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index c95215f4f8b6..a830c5e80657 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -840,92 +840,149 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
840 840
841 /* Setup openpic */ 841 /* Setup openpic */
842 mpic_setup_this_cpu(); 842 mpic_setup_this_cpu();
843}
843 844
844 if (cpu_nr == 0) { 845#ifdef CONFIG_HOTPLUG_CPU
845#ifdef CONFIG_PPC64 846static int smp_core99_cpu_notify(struct notifier_block *self,
846 extern void g5_phy_disable_cpu1(void); 847 unsigned long action, void *hcpu)
848{
849 int rc;
847 850
848 /* Close i2c bus if it was used for tb sync */ 851 switch(action) {
852 case CPU_UP_PREPARE:
853 case CPU_UP_PREPARE_FROZEN:
854 /* Open i2c bus if it was used for tb sync */
849 if (pmac_tb_clock_chip_host) { 855 if (pmac_tb_clock_chip_host) {
850 pmac_i2c_close(pmac_tb_clock_chip_host); 856 rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
851 pmac_tb_clock_chip_host = NULL; 857 if (rc) {
858 pr_err("Failed to open i2c bus for time sync\n");
859 return notifier_from_errno(rc);
860 }
852 } 861 }
862 break;
863 case CPU_ONLINE:
864 case CPU_UP_CANCELED:
865 /* Close i2c bus if it was used for tb sync */
866 if (pmac_tb_clock_chip_host)
867 pmac_i2c_close(pmac_tb_clock_chip_host);
868 break;
869 default:
870 break;
871 }
872 return NOTIFY_OK;
873}
853 874
854 /* If we didn't start the second CPU, we must take 875static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
855 * it off the bus 876 .notifier_call = smp_core99_cpu_notify,
856 */ 877};
857 if (of_machine_is_compatible("MacRISC4") && 878#endif /* CONFIG_HOTPLUG_CPU */
858 num_online_cpus() < 2) 879
859 g5_phy_disable_cpu1(); 880static void __init smp_core99_bringup_done(void)
860#endif /* CONFIG_PPC64 */ 881{
882#ifdef CONFIG_PPC64
883 extern void g5_phy_disable_cpu1(void);
884
885 /* Close i2c bus if it was used for tb sync */
886 if (pmac_tb_clock_chip_host)
887 pmac_i2c_close(pmac_tb_clock_chip_host);
861 888
862 if (ppc_md.progress) 889 /* If we didn't start the second CPU, we must take
863 ppc_md.progress("core99_setup_cpu 0 done", 0x349); 890 * it off the bus.
891 */
892 if (of_machine_is_compatible("MacRISC4") &&
893 num_online_cpus() < 2) {
894 set_cpu_present(1, false);
895 g5_phy_disable_cpu1();
864 } 896 }
865} 897#endif /* CONFIG_PPC64 */
866 898
899#ifdef CONFIG_HOTPLUG_CPU
900 register_cpu_notifier(&smp_core99_cpu_nb);
901#endif
902 if (ppc_md.progress)
903 ppc_md.progress("smp_core99_bringup_done", 0x349);
904}
867 905
868#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) 906#ifdef CONFIG_HOTPLUG_CPU
869 907
870int smp_core99_cpu_disable(void) 908static int smp_core99_cpu_disable(void)
871{ 909{
872 set_cpu_online(smp_processor_id(), false); 910 int rc = generic_cpu_disable();
911 if (rc)
912 return rc;
873 913
874 /* XXX reset cpu affinity here */
875 mpic_cpu_set_priority(0xf); 914 mpic_cpu_set_priority(0xf);
876 asm volatile("mtdec %0" : : "r" (0x7fffffff)); 915
877 mb();
878 udelay(20);
879 asm volatile("mtdec %0" : : "r" (0x7fffffff));
880 return 0; 916 return 0;
881} 917}
882 918
883static int cpu_dead[NR_CPUS]; 919#ifdef CONFIG_PPC32
884 920
885void pmac32_cpu_die(void) 921static void pmac_cpu_die(void)
886{ 922{
923 int cpu = smp_processor_id();
924
887 local_irq_disable(); 925 local_irq_disable();
888 cpu_dead[smp_processor_id()] = 1; 926 idle_task_exit();
927 pr_debug("CPU%d offline\n", cpu);
928 generic_set_cpu_dead(cpu);
929 smp_wmb();
889 mb(); 930 mb();
890 low_cpu_die(); 931 low_cpu_die();
891} 932}
892 933
893void smp_core99_cpu_die(unsigned int cpu) 934#else /* CONFIG_PPC32 */
935
936static void pmac_cpu_die(void)
894{ 937{
895 int timeout; 938 int cpu = smp_processor_id();
896 939
897 timeout = 1000; 940 local_irq_disable();
898 while (!cpu_dead[cpu]) { 941 idle_task_exit();
899 if (--timeout == 0) { 942
900 printk("CPU %u refused to die!\n", cpu); 943 /*
901 break; 944 * turn off as much as possible, we'll be
902 } 945 * kicked out as this will only be invoked
903 msleep(1); 946 * on core99 platforms for now ...
947 */
948
949 printk(KERN_INFO "CPU#%d offline\n", cpu);
950 generic_set_cpu_dead(cpu);
951 smp_wmb();
952
953 /*
954 * Re-enable interrupts. The NAP code needs to enable them
955 * anyways, do it now so we deal with the case where one already
956 * happened while soft-disabled.
957 * We shouldn't get any external interrupts, only decrementer, and the
958 * decrementer handler is safe for use on offline CPUs
959 */
960 local_irq_enable();
961
962 while (1) {
963 /* let's not take timer interrupts too often ... */
964 set_dec(0x7fffffff);
965
966 /* Enter NAP mode */
967 power4_idle();
904 } 968 }
905 cpu_dead[cpu] = 0;
906} 969}
907 970
908#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */ 971#endif /* else CONFIG_PPC32 */
972#endif /* CONFIG_HOTPLUG_CPU */
909 973
910/* Core99 Macs (dual G4s and G5s) */ 974/* Core99 Macs (dual G4s and G5s) */
911struct smp_ops_t core99_smp_ops = { 975struct smp_ops_t core99_smp_ops = {
912 .message_pass = smp_mpic_message_pass, 976 .message_pass = smp_mpic_message_pass,
913 .probe = smp_core99_probe, 977 .probe = smp_core99_probe,
978 .bringup_done = smp_core99_bringup_done,
914 .kick_cpu = smp_core99_kick_cpu, 979 .kick_cpu = smp_core99_kick_cpu,
915 .setup_cpu = smp_core99_setup_cpu, 980 .setup_cpu = smp_core99_setup_cpu,
916 .give_timebase = smp_core99_give_timebase, 981 .give_timebase = smp_core99_give_timebase,
917 .take_timebase = smp_core99_take_timebase, 982 .take_timebase = smp_core99_take_timebase,
918#if defined(CONFIG_HOTPLUG_CPU) 983#if defined(CONFIG_HOTPLUG_CPU)
919# if defined(CONFIG_PPC32)
920 .cpu_disable = smp_core99_cpu_disable, 984 .cpu_disable = smp_core99_cpu_disable,
921 .cpu_die = smp_core99_cpu_die,
922# endif
923# if defined(CONFIG_PPC64)
924 .cpu_disable = generic_cpu_disable,
925 .cpu_die = generic_cpu_die, 985 .cpu_die = generic_cpu_die,
926 /* intentionally do *NOT* assign cpu_enable,
927 * the generic code will use kick_cpu then! */
928# endif
929#endif 986#endif
930}; 987};
931 988
@@ -957,5 +1014,10 @@ void __init pmac_setup_smp(void)
957 smp_ops = &psurge_smp_ops; 1014 smp_ops = &psurge_smp_ops;
958 } 1015 }
959#endif /* CONFIG_PPC32 */ 1016#endif /* CONFIG_PPC32 */
1017
1018#ifdef CONFIG_HOTPLUG_CPU
1019 ppc_md.cpu_die = pmac_cpu_die;
1020#endif
960} 1021}
961 1022
1023