Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2011 15:57:02 +0000 (08:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Apr 2011 15:57:02 +0000 (08:57 -0700)
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  kdump: Allow shrinking of kdump region to be overridden
  powerpc/pmac/smp: Remove no-longer needed preempt workaround
  powerpc/smp: Increase vdso_data->processorCount, not just decrease it
  powerpc/smp: Create idle threads on demand and properly reset them
  powerpc/smp: Don't expose per-cpu "cpu_state" array
  powerpc/pmac/smp: Fix CPU hotplug crashes on some machines
  powerpc/smp: Add a smp_ops->bringup_up() done callback
  powerpc/pmac: Rename cpu_state in therm_pm72 to avoid collision
  powerpc/pmac/smp: Properly NAP offlined CPU on G5
  powerpc/pmac/smp: Remove HMT changes for PowerMac offline code
  powerpc/pmac/smp: Consolidate 32-bit and 64-bit PowerMac cpu_die in one file
  powerpc/pmac/smp: Fixup smp_core99_cpu_disable() and use it on 64-bit
  powerpc/pmac/smp: Rename fixup_irqs() to migrate_irqs() and use it on ppc32
  powerpc/pmac/smp: Fix 32-bit PowerMac cpu_die
  powerpc/smp: Remove unused smp_ops->cpu_enable()
  powerpc/smp: Remove unused generic_cpu_enable()
  powerpc/smp: Fix generic_mach_cpu_die()
  powerpc/smp: soft-replugged CPUs must go back to start_secondary
  powerpc: Make decrementer interrupt robust against offlined CPUs

15 files changed:
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/smp.h
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/idle_power4.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/time.c
arch/powerpc/platforms/powermac/pmac.h
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/pseries/offline_states.h
drivers/macintosh/therm_pm72.c
include/linux/kexec.h
kernel/kexec.c

index fe56a23..e4f0191 100644 (file)
@@ -35,9 +35,9 @@ struct smp_ops_t {
        int   (*probe)(void);
        void  (*kick_cpu)(int nr);
        void  (*setup_cpu)(int nr);
+       void  (*bringup_done)(void);
        void  (*take_timebase)(void);
        void  (*give_timebase)(void);
-       int   (*cpu_enable)(unsigned int nr);
        int   (*cpu_disable)(void);
        void  (*cpu_die)(unsigned int nr);
        int   (*cpu_bootable)(unsigned int nr);
@@ -267,7 +267,6 @@ struct machdep_calls {
 
 extern void e500_idle(void);
 extern void power4_idle(void);
-extern void power4_cpu_offline_powersave(void);
 extern void ppc6xx_idle(void);
 extern void book3e_idle(void);
 
index 66e237b..a902a0d 100644 (file)
@@ -36,15 +36,16 @@ extern void cpu_die(void);
 
 extern void smp_send_debugger_break(int cpu);
 extern void smp_message_recv(int);
+extern void start_secondary_resume(void);
 
 DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
 #ifdef CONFIG_HOTPLUG_CPU
-extern void fixup_irqs(const struct cpumask *map);
+extern void migrate_irqs(void);
 int generic_cpu_disable(void);
-int generic_cpu_enable(unsigned int cpu);
 void generic_cpu_die(unsigned int cpu);
 void generic_mach_cpu_die(void);
+void generic_set_cpu_dead(unsigned int cpu);
 #endif
 
 #ifdef CONFIG_PPC64
index 98c4b29..c5c24be 100644 (file)
@@ -890,6 +890,15 @@ __secondary_start:
        mtspr   SPRN_SRR1,r4
        SYNC
        RFI
+
+_GLOBAL(start_secondary_resume)
+       /* Reset stack */
+       rlwinm  r1,r1,0,0,(31-THREAD_SHIFT)     /* current_thread_info() */
+       addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+       li      r3,0
+       std     r3,0(r1)                /* Zero the stack frame pointer */
+       bl      start_secondary
+       b       .
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_KVM_BOOK3S_HANDLER
index 782f23d..271140b 100644 (file)
@@ -536,6 +536,13 @@ _GLOBAL(pmac_secondary_start)
        add     r13,r13,r4              /* for this processor.          */
        mtspr   SPRN_SPRG_PACA,r13      /* Save vaddr of paca in an SPRG*/
 
+       /* Mark interrupts soft and hard disabled (they might be enabled
+        * in the PACA when doing hotplug)
+        */
+       li      r0,0
+       stb     r0,PACASOFTIRQEN(r13)
+       stb     r0,PACAHARDIRQEN(r13)
+
        /* Create a temp kernel stack for use before relocation is on.  */
        ld      r1,PACAEMERGSP(r13)
        subi    r1,r1,STACK_FRAME_OVERHEAD
index 5328709..ba31954 100644 (file)
@@ -53,24 +53,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        isync
        b       1b
 
-_GLOBAL(power4_cpu_offline_powersave)
-       /* Go to NAP now */
-       mfmsr   r7
-       rldicl  r0,r7,48,1
-       rotldi  r0,r0,16
-       mtmsrd  r0,1                    /* hard-disable interrupts */
-       li      r0,1
-       li      r6,0
-       stb     r0,PACAHARDIRQEN(r13)   /* we'll hard-enable shortly */
-       stb     r6,PACASOFTIRQEN(r13)   /* soft-disable irqs */
-BEGIN_FTR_SECTION
-       DSSALL
-       sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-       ori     r7,r7,MSR_EE
-       oris    r7,r7,MSR_POW@h
-       sync
-       isync
-       mtmsrd  r7
-       isync
-       blr
index 63625e0..f621b7d 100644 (file)
@@ -246,12 +246,13 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(const struct cpumask *map)
+void migrate_irqs(void)
 {
        struct irq_desc *desc;
        unsigned int irq;
        static int warned;
        cpumask_var_t mask;
+       const struct cpumask *map = cpu_online_mask;
 
        alloc_cpumask_var(&mask, GFP_KERNEL);
 
index 9813605..cbdbb14 100644 (file)
 #define DBG(fmt...)
 #endif
 
+
+/* Store all idle threads, this can be reused instead of creating
+* a new thread. Also avoids complicated thread destroy functionality
+* for idle threads.
+*/
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
+ * removed after init for !CONFIG_HOTPLUG_CPU.
+ */
+static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
+#define get_idle_for_cpu(x)      (per_cpu(idle_thread_array, x))
+#define set_idle_for_cpu(x, p)   (per_cpu(idle_thread_array, x) = (p))
+#else
+static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+#define get_idle_for_cpu(x)      (idle_thread_array[(x)])
+#define set_idle_for_cpu(x, p)   (idle_thread_array[(x)] = (p))
+#endif
+
 struct thread_info *secondary_ti;
 
 DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
@@ -238,23 +257,6 @@ static void __devinit smp_store_cpu_info(int id)
        per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
 }
 
-static void __init smp_create_idle(unsigned int cpu)
-{
-       struct task_struct *p;
-
-       /* create a process for the processor */
-       p = fork_idle(cpu);
-       if (IS_ERR(p))
-               panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-#ifdef CONFIG_PPC64
-       paca[cpu].__current = p;
-       paca[cpu].kstack = (unsigned long) task_thread_info(p)
-               + THREAD_SIZE - STACK_FRAME_OVERHEAD;
-#endif
-       current_set[cpu] = task_thread_info(p);
-       task_thread_info(p)->cpu = cpu;
-}
-
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        unsigned int cpu;
@@ -288,10 +290,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                        max_cpus = NR_CPUS;
        else
                max_cpus = 1;
-
-       for_each_possible_cpu(cpu)
-               if (cpu != boot_cpuid)
-                       smp_create_idle(cpu);
 }
 
 void __devinit smp_prepare_boot_cpu(void)
@@ -305,7 +303,7 @@ void __devinit smp_prepare_boot_cpu(void)
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* State of each CPU during hotplug phases */
-DEFINE_PER_CPU(int, cpu_state) = { 0 };
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
 
 int generic_cpu_disable(void)
 {
@@ -317,30 +315,8 @@ int generic_cpu_disable(void)
        set_cpu_online(cpu, false);
 #ifdef CONFIG_PPC64
        vdso_data->processorCount--;
-       fixup_irqs(cpu_online_mask);
-#endif
-       return 0;
-}
-
-int generic_cpu_enable(unsigned int cpu)
-{
-       /* Do the normal bootup if we haven't
-        * already bootstrapped. */
-       if (system_state != SYSTEM_RUNNING)
-               return -ENOSYS;
-
-       /* get the target out of it's holding state */
-       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
-       smp_wmb();
-
-       while (!cpu_online(cpu))
-               cpu_relax();
-
-#ifdef CONFIG_PPC64
-       fixup_irqs(cpu_online_mask);
-       /* counter the irq disable in fixup_irqs */
-       local_irq_enable();
 #endif
+       migrate_irqs();
        return 0;
 }
 
@@ -362,37 +338,89 @@ void generic_mach_cpu_die(void)
        unsigned int cpu;
 
        local_irq_disable();
+       idle_task_exit();
        cpu = smp_processor_id();
        printk(KERN_DEBUG "CPU%d offline\n", cpu);
        __get_cpu_var(cpu_state) = CPU_DEAD;
        smp_wmb();
        while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
                cpu_relax();
-       set_cpu_online(cpu, true);
-       local_irq_enable();
+}
+
+void generic_set_cpu_dead(unsigned int cpu)
+{
+       per_cpu(cpu_state, cpu) = CPU_DEAD;
 }
 #endif
 
-static int __devinit cpu_enable(unsigned int cpu)
+struct create_idle {
+       struct work_struct work;
+       struct task_struct *idle;
+       struct completion done;
+       int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
 {
-       if (smp_ops && smp_ops->cpu_enable)
-               return smp_ops->cpu_enable(cpu);
+       struct create_idle *c_idle =
+               container_of(work, struct create_idle, work);
+
+       c_idle->idle = fork_idle(c_idle->cpu);
+       complete(&c_idle->done);
+}
+
+static int __cpuinit create_idle(unsigned int cpu)
+{
+       struct thread_info *ti;
+       struct create_idle c_idle = {
+               .cpu    = cpu,
+               .done   = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+       };
+       INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+
+       c_idle.idle = get_idle_for_cpu(cpu);
+
+       /* We can't use kernel_thread since we must avoid to
+        * reschedule the child. We use a workqueue because
+        * we want to fork from a kernel thread, not whatever
+        * userspace process happens to be trying to online us.
+        */
+       if (!c_idle.idle) {
+               schedule_work(&c_idle.work);
+               wait_for_completion(&c_idle.done);
+       } else
+               init_idle(c_idle.idle, cpu);
+       if (IS_ERR(c_idle.idle)) {              
+               pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
+               return PTR_ERR(c_idle.idle);
+       }
+       ti = task_thread_info(c_idle.idle);
+
+#ifdef CONFIG_PPC64
+       paca[cpu].__current = c_idle.idle;
+       paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
+#endif
+       ti->cpu = cpu;
+       current_set[cpu] = ti;
 
-       return -ENOSYS;
+       return 0;
 }
 
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-       int c;
+       int rc, c;
 
        secondary_ti = current_set[cpu];
-       if (!cpu_enable(cpu))
-               return 0;
 
        if (smp_ops == NULL ||
            (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
                return -EINVAL;
 
+       /* Make sure we have an idle thread */
+       rc = create_idle(cpu);
+       if (rc)
+               return rc;
+
        /* Make sure callin-map entry is 0 (can be leftover a CPU
         * hotplug
         */
@@ -502,7 +530,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
 }
 
 /* Activate a secondary processor. */
-int __devinit start_secondary(void *unused)
+void __devinit start_secondary(void *unused)
 {
        unsigned int cpu = smp_processor_id();
        struct device_node *l2_cache;
@@ -523,6 +551,10 @@ int __devinit start_secondary(void *unused)
 
        secondary_cpu_time_init();
 
+#ifdef CONFIG_PPC64
+       if (system_state == SYSTEM_RUNNING)
+               vdso_data->processorCount++;
+#endif
        ipi_call_lock();
        notify_cpu_starting(cpu);
        set_cpu_online(cpu, true);
@@ -558,7 +590,8 @@ int __devinit start_secondary(void *unused)
        local_irq_enable();
 
        cpu_idle();
-       return 0;
+
+       BUG();
 }
 
 int setup_profiling_timer(unsigned int multiplier)
@@ -585,7 +618,11 @@ void __init smp_cpus_done(unsigned int max_cpus)
 
        free_cpumask_var(old_mask);
 
+       if (smp_ops && smp_ops->bringup_done)
+               smp_ops->bringup_done();
+
        dump_numa_cpu_topology();
+
 }
 
 int arch_sd_sibling_asym_packing(void)
@@ -660,5 +697,9 @@ void cpu_die(void)
 {
        if (ppc_md.cpu_die)
                ppc_md.cpu_die();
+
+       /* If we return, we re-enter start_secondary */
+       start_secondary_resume();
 }
+
 #endif
index aa92696..375480c 100644 (file)
@@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs)
        struct clock_event_device *evt = &decrementer->event;
        u64 now;
 
+       /* Ensure a positive value is written to the decrementer, or else
+        * some CPUs will continue to take decrementer exceptions.
+        */
+       set_dec(DECREMENTER_MAX);
+
+       /* Some implementations of hotplug will get timer interrupts while
+        * offline, just ignore these
+        */
+       if (!cpu_online(smp_processor_id()))
+               return;
+
        trace_timer_interrupt_entry(regs);
 
        __get_cpu_var(irq_stat).timer_irqs++;
 
-       /* Ensure a positive value is written to the decrementer, or else
-        * some CPUs will continuue to take decrementer exceptions */
-       set_dec(DECREMENTER_MAX);
-
 #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
        if (atomic_read(&ppc_n_lost_interrupts) != 0)
                do_IRQ(regs);
index f0bc08f..20468f4 100644 (file)
@@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void);
 extern void pmac_check_ht_link(void);
 
 extern void pmac_setup_smp(void);
-extern void pmac32_cpu_die(void);
 extern void low_cpu_die(void) __attribute__((noreturn));
 
 extern int pmac_nvram_init(void);
index d5aceb7..aa45281 100644 (file)
@@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
                return PCI_PROBE_NORMAL;
        return PCI_PROBE_DEVTREE;
 }
-
-#ifdef CONFIG_HOTPLUG_CPU
-/* access per cpu vars from generic smp.c */
-DECLARE_PER_CPU(int, cpu_state);
-
-static void pmac64_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) {
@@ -726,15 +681,4 @@ define_machine(powermac) {
        .pcibios_after_init     = pmac_pcibios_after_init,
        .phys_mem_access_prot   = pci_phys_mem_access_prot,
 #endif
-#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_PPC64
-       .cpu_die                = pmac64_cpu_die,
-#endif
-#ifdef CONFIG_PPC32
-       .cpu_die                = pmac32_cpu_die,
-#endif
-#endif
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
-       .cpu_die                = generic_mach_cpu_die,
-#endif
 };
index c95215f..a830c5e 100644 (file)
@@ -840,92 +840,149 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
 
        /* Setup openpic */
        mpic_setup_this_cpu();
+}
 
-       if (cpu_nr == 0) {
-#ifdef CONFIG_PPC64
-               extern void g5_phy_disable_cpu1(void);
+#ifdef CONFIG_HOTPLUG_CPU
+static int smp_core99_cpu_notify(struct notifier_block *self,
+                                unsigned long action, void *hcpu)
+{
+       int rc;
 
-               /* Close i2c bus if it was used for tb sync */
+       switch(action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+               /* Open i2c bus if it was used for tb sync */
                if (pmac_tb_clock_chip_host) {
-                       pmac_i2c_close(pmac_tb_clock_chip_host);
-                       pmac_tb_clock_chip_host = NULL;
+                       rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
+                       if (rc) {
+                               pr_err("Failed to open i2c bus for time sync\n");
+                               return notifier_from_errno(rc);
+                       }
                }
+               break;
+       case CPU_ONLINE:
+       case CPU_UP_CANCELED:
+               /* Close i2c bus if it was used for tb sync */
+               if (pmac_tb_clock_chip_host)
+                       pmac_i2c_close(pmac_tb_clock_chip_host);
+               break;
+       default:
+               break;
+       }
+       return NOTIFY_OK;
+}
 
-               /* If we didn't start the second CPU, we must take
-                * it off the bus
-                */
-               if (of_machine_is_compatible("MacRISC4") &&
-                   num_online_cpus() < 2)              
-                       g5_phy_disable_cpu1();
-#endif /* CONFIG_PPC64 */
+static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+       .notifier_call  = smp_core99_cpu_notify,
+};
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static void __init smp_core99_bringup_done(void)
+{
+#ifdef CONFIG_PPC64
+       extern void g5_phy_disable_cpu1(void);
+
+       /* Close i2c bus if it was used for tb sync */
+       if (pmac_tb_clock_chip_host)
+               pmac_i2c_close(pmac_tb_clock_chip_host);
 
-               if (ppc_md.progress)
-                       ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+       /* If we didn't start the second CPU, we must take
+        * it off the bus.
+        */
+       if (of_machine_is_compatible("MacRISC4") &&
+           num_online_cpus() < 2) {
+               set_cpu_present(1, false);
+               g5_phy_disable_cpu1();
        }
-}
+#endif /* CONFIG_PPC64 */
 
+#ifdef CONFIG_HOTPLUG_CPU
+       register_cpu_notifier(&smp_core99_cpu_nb);
+#endif
+       if (ppc_md.progress)
+               ppc_md.progress("smp_core99_bringup_done", 0x349);
+}
 
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+#ifdef CONFIG_HOTPLUG_CPU
 
-int smp_core99_cpu_disable(void)
+static int smp_core99_cpu_disable(void)
 {
-       set_cpu_online(smp_processor_id(), false);
+       int rc = generic_cpu_disable();
+       if (rc)
+               return rc;
 
-       /* XXX reset cpu affinity here */
        mpic_cpu_set_priority(0xf);
-       asm volatile("mtdec %0" : : "r" (0x7fffffff));
-       mb();
-       udelay(20);
-       asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
        return 0;
 }
 
-static int cpu_dead[NR_CPUS];
+#ifdef CONFIG_PPC32
 
-void pmac32_cpu_die(void)
+static void pmac_cpu_die(void)
 {
+       int cpu = smp_processor_id();
+
        local_irq_disable();
-       cpu_dead[smp_processor_id()] = 1;
+       idle_task_exit();
+       pr_debug("CPU%d offline\n", cpu);
+       generic_set_cpu_dead(cpu);
+       smp_wmb();
        mb();
        low_cpu_die();
 }
 
-void smp_core99_cpu_die(unsigned int cpu)
+#else /* CONFIG_PPC32 */
+
+static void pmac_cpu_die(void)
 {
-       int timeout;
+       int cpu = smp_processor_id();
 
-       timeout = 1000;
-       while (!cpu_dead[cpu]) {
-               if (--timeout == 0) {
-                       printk("CPU %u refused to die!\n", cpu);
-                       break;
-               }
-               msleep(1);
+       local_irq_disable();
+       idle_task_exit();
+
+       /*
+        * 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", cpu);
+       generic_set_cpu_dead(cpu);
+       smp_wmb();
+
+       /*
+        * Re-enable interrupts. The NAP code needs to enable them
+        * anyways, do it now so we deal with the case where one already
+        * happened while soft-disabled.
+        * We shouldn't get any external interrupts, only decrementer, and the
+        * decrementer handler is safe for use on offline CPUs
+        */
+       local_irq_enable();
+
+       while (1) {
+               /* let's not take timer interrupts too often ... */
+               set_dec(0x7fffffff);
+
+               /* Enter NAP mode */
+               power4_idle();
        }
-       cpu_dead[cpu] = 0;
 }
 
-#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
+#endif /* else CONFIG_PPC32 */
+#endif /* CONFIG_HOTPLUG_CPU */
 
 /* Core99 Macs (dual G4s and G5s) */
 struct smp_ops_t core99_smp_ops = {
        .message_pass   = smp_mpic_message_pass,
        .probe          = smp_core99_probe,
+       .bringup_done   = smp_core99_bringup_done,
        .kick_cpu       = smp_core99_kick_cpu,
        .setup_cpu      = smp_core99_setup_cpu,
        .give_timebase  = smp_core99_give_timebase,
        .take_timebase  = smp_core99_take_timebase,
 #if defined(CONFIG_HOTPLUG_CPU)
-# if defined(CONFIG_PPC32)
        .cpu_disable    = smp_core99_cpu_disable,
-       .cpu_die        = smp_core99_cpu_die,
-# endif
-# if defined(CONFIG_PPC64)
-       .cpu_disable    = generic_cpu_disable,
        .cpu_die        = generic_cpu_die,
-       /* intentionally do *NOT* assign cpu_enable,
-        * the generic code will use kick_cpu then! */
-# endif
 #endif
 };
 
@@ -957,5 +1014,10 @@ void __init pmac_setup_smp(void)
                smp_ops = &psurge_smp_ops;
        }
 #endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_HOTPLUG_CPU
+       ppc_md.cpu_die = pmac_cpu_die;
+#endif
 }
 
+
index 75a6f48..08672d9 100644 (file)
@@ -34,6 +34,4 @@ static inline void set_default_offline_state(int cpu)
 #endif
 
 extern enum cpu_state_vals get_preferred_offline_state(int cpu);
-extern int start_secondary(void);
-extern void start_secondary_resume(void);
 #endif
index bca2af2..c987033 100644 (file)
@@ -153,7 +153,7 @@ static struct i2c_adapter *         u3_0;
 static struct i2c_adapter *            u3_1;
 static struct i2c_adapter *            k2;
 static struct i2c_client *             fcu;
-static struct cpu_pid_state            cpu_state[2];
+static struct cpu_pid_state            processor_state[2];
 static struct basckside_pid_params     backside_params;
 static struct backside_pid_state       backside_state;
 static struct drives_pid_state         drives_state;
@@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out)
 
 static void fetch_cpu_pumps_minmax(void)
 {
-       struct cpu_pid_state *state0 = &cpu_state[0];
-       struct cpu_pid_state *state1 = &cpu_state[1];
+       struct cpu_pid_state *state0 = &processor_state[0];
+       struct cpu_pid_state *state1 = &processor_state[1];
        u16 pump_min = 0, pump_max = 0xffff;
        u16 tmp[4];
 
@@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
        return sprintf(buf, "%d", data);                        \
 }
 
-BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage)
-BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a)
-BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm)
-BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
+BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
+BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
+BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
 
-BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage)
-BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a)
-BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm)
-BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
+BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
+BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
+BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
 
 BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
 BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
@@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power)
 
 static void do_monitor_cpu_combined(void)
 {
-       struct cpu_pid_state *state0 = &cpu_state[0];
-       struct cpu_pid_state *state1 = &cpu_state[1];
+       struct cpu_pid_state *state0 = &processor_state[0];
+       struct cpu_pid_state *state1 = &processor_state[1];
        s32 temp0, power0, temp1, power1;
        s32 temp_combi, power_combi;
        int rc, intake, pump;
@@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
 /*
  * Initialize the state structure for one CPU control loop
  */
-static int init_cpu_state(struct cpu_pid_state *state, int index)
+static int init_processor_state(struct cpu_pid_state *state, int index)
 {
        int err;
 
@@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
 /*
  * Dispose of the state data for one CPU control loop
  */
-static void dispose_cpu_state(struct cpu_pid_state *state)
+static void dispose_processor_state(struct cpu_pid_state *state)
 {
        if (state->monitor == NULL)
                return;
@@ -1804,9 +1804,9 @@ static int main_control_loop(void *x)
                set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
 
        /* Initialize ADCs */
-       initialize_adc(&cpu_state[0]);
-       if (cpu_state[1].monitor != NULL)
-               initialize_adc(&cpu_state[1]);
+       initialize_adc(&processor_state[0]);
+       if (processor_state[1].monitor != NULL)
+               initialize_adc(&processor_state[1]);
 
        fcu_tickle_ticks = FCU_TICKLE_TICKS;
 
@@ -1833,14 +1833,14 @@ static int main_control_loop(void *x)
                if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
                        do_monitor_cpu_combined();
                else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
-                       do_monitor_cpu_rack(&cpu_state[0]);
-                       if (cpu_state[1].monitor != NULL)
-                               do_monitor_cpu_rack(&cpu_state[1]);
+                       do_monitor_cpu_rack(&processor_state[0]);
+                       if (processor_state[1].monitor != NULL)
+                               do_monitor_cpu_rack(&processor_state[1]);
                        // better deal with UP
                } else {
-                       do_monitor_cpu_split(&cpu_state[0]);
-                       if (cpu_state[1].monitor != NULL)
-                               do_monitor_cpu_split(&cpu_state[1]);
+                       do_monitor_cpu_split(&processor_state[0]);
+                       if (processor_state[1].monitor != NULL)
+                               do_monitor_cpu_split(&processor_state[1]);
                        // better deal with UP
                }
                /* Then, the rest */
@@ -1885,8 +1885,8 @@ static int main_control_loop(void *x)
  */
 static void dispose_control_loops(void)
 {
-       dispose_cpu_state(&cpu_state[0]);
-       dispose_cpu_state(&cpu_state[1]);
+       dispose_processor_state(&processor_state[0]);
+       dispose_processor_state(&processor_state[1]);
        dispose_backside_state(&backside_state);
        dispose_drives_state(&drives_state);
        dispose_slots_state(&slots_state);
@@ -1928,12 +1928,12 @@ static int create_control_loops(void)
        /* Create control loops for everything. If any fail, everything
         * fails
         */
-       if (init_cpu_state(&cpu_state[0], 0))
+       if (init_processor_state(&processor_state[0], 0))
                goto fail;
        if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
                fetch_cpu_pumps_minmax();
 
-       if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1))
+       if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
                goto fail;
        if (init_backside_state(&backside_state))
                goto fail;
index 03e8e8d..c2478a3 100644 (file)
@@ -208,6 +208,7 @@ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
                unsigned long long *crash_size, unsigned long long *crash_base);
 int crash_shrink_memory(unsigned long new_size);
 size_t crash_get_memory_size(void);
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
 
 #else /* !CONFIG_KEXEC */
 struct pt_regs;
index ec19b92..4e240a3 100644 (file)
@@ -1099,7 +1099,8 @@ size_t crash_get_memory_size(void)
        return size;
 }
 
-static void free_reserved_phys_range(unsigned long begin, unsigned long end)
+void __weak crash_free_reserved_phys_range(unsigned long begin,
+                                          unsigned long end)
 {
        unsigned long addr;
 
@@ -1135,7 +1136,7 @@ int crash_shrink_memory(unsigned long new_size)
        start = roundup(start, PAGE_SIZE);
        end = roundup(start + new_size, PAGE_SIZE);
 
-       free_reserved_phys_range(end, crashk_res.end);
+       crash_free_reserved_phys_range(end, crashk_res.end);
 
        if ((start == end) && (crashk_res.parent != NULL))
                release_resource(&crashk_res);