aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powermac/setup.c')
-rw-r--r--arch/powerpc/platforms/powermac/setup.c121
1 files changed, 52 insertions, 69 deletions
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b820cabac697..a410bc76a8a8 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -439,76 +439,14 @@ static void __init find_boot_device(void)
439#endif 439#endif
440} 440}
441 441
442/* TODO: Merge the suspend-to-ram with the common code !!!
443 * currently, this is a stub implementation for suspend-to-disk
444 * only
445 */
446
447#ifdef CONFIG_SOFTWARE_SUSPEND
448
449static int pmac_pm_prepare(suspend_state_t state)
450{
451 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
452
453 return 0;
454}
455
456static int pmac_pm_enter(suspend_state_t state)
457{
458 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
459
460 /* Giveup the lazy FPU & vec so we don't have to back them
461 * up from the low level code
462 */
463 enable_kernel_fp();
464
465#ifdef CONFIG_ALTIVEC
466 if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
467 enable_kernel_altivec();
468#endif /* CONFIG_ALTIVEC */
469
470 return 0;
471}
472
473static int pmac_pm_finish(suspend_state_t state)
474{
475 printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
476
477 /* Restore userland MMU context */
478 set_context(current->active_mm->context.id, current->active_mm->pgd);
479
480 return 0;
481}
482
483static int pmac_pm_valid(suspend_state_t state)
484{
485 switch (state) {
486 case PM_SUSPEND_DISK:
487 return 1;
488 /* can't do any other states via generic mechanism yet */
489 default:
490 return 0;
491 }
492}
493
494static struct pm_ops pmac_pm_ops = {
495 .pm_disk_mode = PM_DISK_SHUTDOWN,
496 .prepare = pmac_pm_prepare,
497 .enter = pmac_pm_enter,
498 .finish = pmac_pm_finish,
499 .valid = pmac_pm_valid,
500};
501
502#endif /* CONFIG_SOFTWARE_SUSPEND */
503
504static int initializing = 1; 442static int initializing = 1;
505 443
506static int pmac_late_init(void) 444static int pmac_late_init(void)
507{ 445{
508 initializing = 0; 446 initializing = 0;
509#ifdef CONFIG_SOFTWARE_SUSPEND 447 /* this is udbg (which is __init) and we can later use it during
510 pm_set_ops(&pmac_pm_ops); 448 * cpu hotplug (in smp_core99_kick_cpu) */
511#endif /* CONFIG_SOFTWARE_SUSPEND */ 449 ppc_md.progress = NULL;
512 return 0; 450 return 0;
513} 451}
514 452
@@ -721,12 +659,57 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
721 /* We need to use normal PCI probing for the AGP bus, 659 /* We need to use normal PCI probing for the AGP bus,
722 * since the device for the AGP bridge isn't in the tree. 660 * since the device for the AGP bridge isn't in the tree.
723 */ 661 */
724 if (bus->self == NULL && (device_is_compatible(node, "u3-agp") || 662 if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
725 device_is_compatible(node, "u4-pcie"))) 663 of_device_is_compatible(node, "u4-pcie")))
726 return PCI_PROBE_NORMAL; 664 return PCI_PROBE_NORMAL;
727 return PCI_PROBE_DEVTREE; 665 return PCI_PROBE_DEVTREE;
728} 666}
729#endif 667
668#ifdef CONFIG_HOTPLUG_CPU
669/* access per cpu vars from generic smp.c */
670DECLARE_PER_CPU(int, cpu_state);
671
672static void pmac_cpu_die(void)
673{
674 /*
675 * turn off as much as possible, we'll be
676 * kicked out as this will only be invoked
677 * on core99 platforms for now ...
678 */
679
680 printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
681 __get_cpu_var(cpu_state) = CPU_DEAD;
682 smp_wmb();
683
684 /*
685 * during the path that leads here preemption is disabled,
686 * reenable it now so that when coming up preempt count is
687 * zero correctly
688 */
689 preempt_enable();
690
691 /*
692 * hard-disable interrupts for the non-NAP case, the NAP code
693 * needs to re-enable interrupts (but soft-disables them)
694 */
695 hard_irq_disable();
696
697 while (1) {
698 /* let's not take timer interrupts too often ... */
699 set_dec(0x7fffffff);
700
701 /* should always be true at this point */
702 if (cpu_has_feature(CPU_FTR_CAN_NAP))
703 power4_cpu_offline_powersave();
704 else {
705 HMT_low();
706 HMT_very_low();
707 }
708 }
709}
710#endif /* CONFIG_HOTPLUG_CPU */
711
712#endif /* CONFIG_PPC64 */
730 713
731define_machine(powermac) { 714define_machine(powermac) {
732 .name = "PowerMac", 715 .name = "PowerMac",
@@ -763,6 +746,6 @@ define_machine(powermac) {
763 .phys_mem_access_prot = pci_phys_mem_access_prot, 746 .phys_mem_access_prot = pci_phys_mem_access_prot,
764#endif 747#endif
765#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) 748#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
766 .cpu_die = generic_mach_cpu_die, 749 .cpu_die = pmac_cpu_die,
767#endif 750#endif
768}; 751};