diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac/setup.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 5ae57e17d2b..e365bff74d8 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -444,6 +444,9 @@ static int initializing = 1; static int pmac_late_init(void) { initializing = 0; + /* this is udbg (which is __init) and we can later use it during + * cpu hotplug (in smp_core99_kick_cpu) */ + ppc_md.progress = NULL; return 0; } @@ -661,7 +664,52 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) return PCI_PROBE_NORMAL; return PCI_PROBE_DEVTREE; } -#endif + +#ifdef CONFIG_HOTPLUG_CPU +/* access per cpu vars from generic smp.c */ +DECLARE_PER_CPU(int, cpu_state); + +static void pmac_cpu_die(void) +{ + /* + * turn off as much as possible, we'll be + * kicked out as this will only be invoked + * on core99 platforms for now ... + */ + + printk(KERN_INFO "CPU#%d offline\n", smp_processor_id()); + __get_cpu_var(cpu_state) = CPU_DEAD; + smp_wmb(); + + /* + * during the path that leads here preemption is disabled, + * reenable it now so that when coming up preempt count is + * zero correctly + */ + preempt_enable(); + + /* + * hard-disable interrupts for the non-NAP case, the NAP code + * needs to re-enable interrupts (but soft-disables them) + */ + hard_irq_disable(); + + while (1) { + /* let's not take timer interrupts too often ... */ + set_dec(0x7fffffff); + + /* should always be true at this point */ + if (cpu_has_feature(CPU_FTR_CAN_NAP)) + power4_cpu_offline_powersave(); + else { + HMT_low(); + HMT_very_low(); + } + } +} +#endif /* CONFIG_HOTPLUG_CPU */ + +#endif /* CONFIG_PPC64 */ define_machine(powermac) { .name = "PowerMac", @@ -698,6 +746,6 @@ define_machine(powermac) { .phys_mem_access_prot = pci_phys_mem_access_prot, #endif #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = generic_mach_cpu_die, + .cpu_die = pmac_cpu_die, #endif }; |