]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/powermac/setup.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / powermac / setup.c
index b820cabac697ceef08d9a786ded2e37ccbe1df3e..7ccb9236e8b485580c5be98f69ed5858e4cda3a5 100644 (file)
@@ -363,8 +363,19 @@ static void __init pmac_setup_arch(void)
                smp_ops = &core99_smp_ops;
        }
 #ifdef CONFIG_PPC32
-       else
+       else {
+               /*
+                * We have to set bits in cpu_possible_map here since the
+                * secondary CPU(s) aren't in the device tree, and
+                * setup_per_cpu_areas only allocates per-cpu data for
+                * CPUs in the cpu_possible_map.
+                */
+               int cpu;
+
+               for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
+                       cpu_set(cpu, cpu_possible_map);
                smp_ops = &psurge_smp_ops;
+       }
 #endif
 #endif /* CONFIG_SMP */
 
@@ -384,7 +395,7 @@ int boot_part;
 static dev_t boot_dev;
 
 #ifdef CONFIG_SCSI
-void __init note_scsi_host(struct device_node *node, void *host)
+void note_scsi_host(struct device_node *node, void *host)
 {
        int l;
        char *p;
@@ -439,76 +450,17 @@ static void __init find_boot_device(void)
 #endif
 }
 
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
-       printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-       return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
-       printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-       /* Giveup the lazy FPU & vec so we don't have to back them
-        * up from the low level code
-        */
-       enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
-       if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
-               enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
-       return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
-       printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-       /* Restore userland MMU context */
-       set_context(current->active_mm->context.id, current->active_mm->pgd);
-
-       return 0;
-}
-
-static int pmac_pm_valid(suspend_state_t state)
-{
-       switch (state) {
-       case PM_SUSPEND_DISK:
-               return 1;
-       /* can't do any other states via generic mechanism yet */
-       default:
-               return 0;
-       }
-}
-
-static struct pm_ops pmac_pm_ops = {
-       .pm_disk_mode   = PM_DISK_SHUTDOWN,
-       .prepare        = pmac_pm_prepare,
-       .enter          = pmac_pm_enter,
-       .finish         = pmac_pm_finish,
-       .valid          = pmac_pm_valid,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
 static int initializing = 1;
 
 static int pmac_late_init(void)
 {
+       if (!machine_is(powermac))
+               return -ENODEV;
+
        initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
-       pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
+       /* 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;
 }
 
@@ -721,12 +673,57 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
        /* We need to use normal PCI probing for the AGP bus,
         * since the device for the AGP bridge isn't in the tree.
         */
-       if (bus->self == NULL && (device_is_compatible(node, "u3-agp") ||
-                                 device_is_compatible(node, "u4-pcie")))
+       if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
+                                 of_device_is_compatible(node, "u4-pcie")))
                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",
@@ -763,6 +760,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
 };