suspend on G5
Subsystems (4)
cover suspend on G5
Hi,
This is a repost of my suspend for G5 patches. It's RFC instead of PATCH because it relies on some patches that Rafael Wysocki did to remove the pageflags that are used for suspend, so it can't be applied as-is without having those patches too. They can be found with the patch titles
* swsusp: Use inline functions for changing page flags
* swsusp: Do not use page flags
* mm: Remove unused page flags
In addition to that patch, you'll need my patch
* swsusp: introduce register_nosave_region_late
which I posted to linux-pm in one of the
"swsusp: Do not use page flags (was: Re: Remove page flags for software suspend)" threads.
All these patches should also be somewhere on
http://johannes.sipsolutions.net/patches/, the first three named rafael{1,2,3}.patch.
johannes
RFC 1/6 powermac: support G5 CPU hotplug
This patch allows "hotplugging" of CPUs on G5 machines. CPUs that are disabled are put into an idle loop with the decrementer frequency set to minimum. To wake them up again we kick them just like when bringing them up. To stop those CPUs from messing with any global state we stop them from entering the timer interrupt.
--- arch/powerpc/kernel/idle_power4.S | 14 +++++++++--- arch/powerpc/platforms/powermac/setup.c | 35 +++++++++++++++++++++++++++++++- arch/powerpc/platforms/powermac/smp.c | 12 +++++++++- include/asm-powerpc/machdep.h | 2 + 4 files changed, 56 insertions(+), 7 deletions(-)
arch/powerpc/platforms/powermac/smp.c +10 -2
@@ -897,7 +897,7 @@ void smp_core99_cpu_die(unsigned int cpu cpu_dead[cpu] =0 ; } -#endif +#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */ /* Core99 Macs (dual G4s and G5s) */ struct smp_ops_t core99_smp_ops = {
@@ -907,8 +907,16 @@ struct smp_ops_t core99_smp_ops = { .setup_cpu = smp_core99_setup_cpu, .give_timebase = smp_core99_give_timebase, .take_timebase = smp_core99_take_timebase, -#if defined(CONFIG_HOTPLUG_CPU ) && defined(CONFIG_PPC32 ) +#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 };
arch/powerpc/platforms/powermac/setup.c +34 -1
@@ -425,6 +425,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 ; }
@@ -651,6 +654,36 @@ static int pmac_pci_probe_mode(struct pcreturn 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 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 (); + +while (1 ) { +/* let's not take timer interrupts too often ... */ +set_dec (0x7fffffff ); +printk ("CPU %d dead\n" ,smp_processor_id ()); + +power4_idle_irqs_softdisabled (); + } +} +#endif +#endif define_machine (powermac) {
@@ -689,6 +722,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 };
arch/powerpc/kernel/idle_power4.S +10 -4
@@ -19,7 +19,12 @@ .text +_GLOBAL(power4_idle_irqs_softdisabled) + li r6,0 + b 0f _GLOBAL(power4_idle) + li r6,1 +0: BEGIN_FTR_SECTION blr END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
@@ -35,8 +40,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) rotldi r0,r0,16 mtmsrd r0,1 /* hard-disable interrupts */ li r0,1 - stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */ - stb r0,PACAHARDIRQEN(r13) + stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */ + stb r6,PACASOFTIRQEN(r13) /* set softirqs enabled bit */ BEGIN_FTR_SECTION DSSALL sync
@@ -51,5 +56,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) isync mtmsrd r7 isync - b 1b - + cmpdi 0,r6,0 + bne+ 1b /* return for softirq-disabled case */ + blr
include/asm-powerpc/machdep.h +2 -0
@@ -252,6 +252,8 @@ struct machdep_calls {extern void power4_idle (void );extern void ppc6xx_idle (void ); +/* this one is for CPU hotplug (e.g. powermac) */ +extern void power4_idle_irqs_softdisabled (void );/* * ppc_md contains a copy of the machine description structure for the
--
RFC 2/6 powerpc: MPIC sys_device & suspend/resume
In reply to Johannes BergThis adds mpic to the system devices and implements suspend and resume for them. This is necessary to get interrupts for modules back to where they were before a suspend to disk.
---
Without this patch, i2sbus (built as a module) for example doesn't work properly across a suspend-to-disk/resume cycle, with this patch it works fine.
I'm not entirely sure if there should be some wait logic after I restore the MPIC registers, it works as-is for me.
Over the previous version of this patch this changes that it also restores the HT interrupts if necessary, making my quad G5 actually work.
--- arch/powerpc/sysdev/mpic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- include/asm-powerpc/mpic.h | 15 +++++++ 2 files changed, 110 insertions(+), 1 deletion(-)
arch/powerpc/sysdev/mpic.c +95 -1
@@ -354,6 +354,12 @@ static void mpic_startup_ht_interrupt(st tmp |=0x22 ;writel (tmp, fixup->base +4 );spin_unlock_irqrestore (&mpic->fixup_lock, flags); + +#ifdef CONFIG_PM +/* use the lowest bit inverted to the actual HW, +* set if this fixup was enabled, clear otherwise */ + mpic->save_data[source].fixup_data = tmp |1 ; +#endif } static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
@@ -375,6 +381,12 @@ static void mpic_shutdown_ht_interrupt(s tmp |=1 ;writel (tmp, fixup->base +4 );spin_unlock_irqrestore (&mpic->fixup_lock, flags); + +#ifdef CONFIG_PM +/* use the lowest bit inverted to the actual HW, +* set if this fixup was enabled, clear otherwise */ + mpic->save_data[source].fixup_data = tmp & ~1 ; +#endif } static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
@@ -1143,7 +1155,7 @@ void __init mpic_init(struct mpic *mpic)/* Do the HT PIC fixups on U3 broken mpic */ DBG ("MPIC flags: %x\n" , mpic->flags);if ((mpic->flags &MPIC_BROKEN_U3 ) && (mpic->flags &MPIC_PRIMARY )) -mpic_scan_ht_pics (mpic); +mpic_scan_ht_pics (mpic);for (i =0 ; i < mpic->num_sources; i++) {/* start with vector = source number, and masked */
@@ -1167,6 +1179,12 @@ void __init mpic_init(struct mpic *mpic)/* Set current processor priority to 0 */ mpic_cpu_write (MPIC_INFO (CPU_CURRENT_TASK_PRI ),0 ); + +#ifdef CONFIG_PM +/* allocate memory to save mpic state */ + mpic->save_data =alloc_bootmem (mpic->num_sources *sizeof (struct mpic_irq_save )); +BUG_ON (mpic->save_data ==NULL ); +#endif }void __init mpic_set_clk_ratio (struct mpic *mpic,u32 clock_ratio)
@@ -1417,3 +1435,79 @@ void __devinit smp_mpic_setup_cpu(int cpmpic_setup_this_cpu (); }#endif /* CONFIG_SMP */ + +#ifdef CONFIG_PM +static int mpic_suspend (struct sys_device *dev,pm_message_t state) +{ + struct mpic *mpic = container_of(dev, struct mpic, sysdev); +int i; + +for (i =0 ; i < mpic->num_sources; i++) { + mpic->save_data[i].vecprio = +mpic_irq_read (i,MPIC_INFO (IRQ_VECTOR_PRI )); + mpic->save_data[i].dest = +mpic_irq_read (i,MPIC_INFO (IRQ_DESTINATION )); + } + +return 0 ; +} + +static int mpic_resume (struct sys_device *dev) +{ + struct mpic *mpic = container_of(dev, struct mpic, sysdev); +int i; + +for (i =0 ; i < mpic->num_sources; i++) { +mpic_irq_write (i,MPIC_INFO (IRQ_VECTOR_PRI ), + mpic->save_data[i].vecprio); +mpic_irq_write (i,MPIC_INFO (IRQ_DESTINATION ), + mpic->save_data[i].dest); + +#ifdef CONFIG_MPIC_BROKEN_U3 + { +struct mpic_irq_fixup *fixup = &mpic->fixups[i]; + +if (fixup->base) { +/* we use the lowest bit in an inverted meaning */ +if ((mpic->save_data[i].fixup_data &1 ) ==0 ) +continue ; + +/* Enable and configure */ +writeb (0x10 +2 * fixup->index, fixup->base +2 ); + +writel (mpic->save_data[i].fixup_data & ~1 , + fixup->base +4 ); + } + } +#endif + }/* end for loop */ + +return 0 ; +} +#endif + +static struct sysdev_class mpic_sysclass = { +#ifdef CONFIG_PM + .resume = mpic_resume, + .suspend = mpic_suspend, +#endif +set_kset_name ("mpic" ), +}; + +static int mpic_init_sys (void ) +{ +struct mpic *mpic = mpics; +int error, id =0 ; + + error =sysdev_class_register (&mpic_sysclass); + +while (mpic && !error) { + mpic->sysdev.cls = &mpic_sysclass; + mpic->sysdev.id = id++; + error =sysdev_register (&mpic->sysdev); + mpic = mpic->next; + } +return error; +} + +device_initcall (mpic_init_sys);
include/asm-powerpc/mpic.h +15 -0
@@ -3,6 +3,7 @@#ifdef __KERNEL__#include <linux/irq.h> +#include <linux/sysdev.h> #include <asm/dcr.h> /*
@@ -228,6 +229,14 @@ struct mpic_reg_bank {#endif /* CONFIG_PPC_DCR */ }; +struct mpic_irq_save { +u32 vecprio, + dest; +#ifdef CONFIG_MPIC_BROKEN_U3 +u32 fixup_data; +#endif +}; +/* The instance data of a given MPIC */ struct mpic {
@@ -294,6 +303,12 @@ struct mpic/* link */ struct mpic *next; + +struct sys_device sysdev; + +#ifdef CONFIG_PM +struct mpic_irq_save *save_data; +#endif };/*
--
RFC 3/6 powerpc: dart iommu suspend
In reply to Johannes BergThis implements save and restore hooks for IOMMUs and implements it the dart iommu.
--- arch/powerpc/sysdev/dart_iommu.c | 46 +++++++++++++++++++++++++++++++++++++++ include/asm-powerpc/iommu.h | 14 +++++++++++ include/asm-powerpc/machdep.h | 5 ++++ 3 files changed, 65 insertions(+)
arch/powerpc/sysdev/dart_iommu.c +46 -0
@@ -36,6 +36,7 @@#include <linux/pci.h> #include <linux/dma-mapping.h> #include <linux/vmalloc.h> +#include <linux/suspend.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/iommu.h>
@@ -54,6 +55,9 @@ static unsigned long dart_tablesize;/* Virtual base address of the DART table */ static u32 *dart_vbase; +#ifdef CONFIG_PM +static u32 *dart_copy; +#endif /* Mapped base address for the dart */ static unsigned int __iomem *dart;
@@ -346,6 +350,48 @@ void iommu_init_early_dart(void) pci_dma_ops = &dma_direct_ops; } +#ifdef CONFIG_PM +static void iommu_dart_save (void ) +{ +memcpy (dart_copy, dart_vbase,2 *1024 *1024 ); +} + +static void iommu_dart_restore (void ) +{ +memcpy (dart_vbase, dart_copy,2 *1024 *1024 ); +dart_tlb_invalidate_all (); +} + +static int __init iommu_init_late_dart (void ) +{ +unsigned long tbasepfn; +struct page *p; + +/* if no dart table exists then we won't need to save it +* and the area has also not been reserved */ +if (!dart_tablebase) +return 0 ; + + tbasepfn =__pa (dart_tablebase) >>PAGE_SHIFT ; +register_nosave_region_late (tbasepfn, + tbasepfn + ((1 <<24 ) >>PAGE_SHIFT )); + +/* For suspend we need to copy the dart contents because +* it is not part of the regular mapping (see above) and +* thus not saved automatically. The memory for this copy +* must be allocated early because we need 2 MB. */ + p =alloc_pages (GFP_KERNEL ,21 -PAGE_SHIFT ); +BUG_ON (!p); + dart_copy =page_address (p); + + ppc_md.iommu_save = iommu_dart_save; + ppc_md.iommu_restore = iommu_dart_restore; + +return 0 ; +} + +late_initcall (iommu_init_late_dart); +#endif void __init alloc_dart_table (void ) {
include/asm-powerpc/iommu.h +14 -0
@@ -26,6 +26,7 @@#include <linux/spinlock.h> #include <linux/device.h> #include <linux/dma-mapping.h> +#include <asm/machdep.h> #include <asm/types.h> #include <asm/bitops.h>
@@ -109,6 +110,19 @@ static inline void pci_iommu_init(void)#endif extern void alloc_dart_table (void ); +#if defined(CONFIG_PPC64 ) && defined(CONFIG_PM ) +static inline void iommu_save (void ) +{ +if (ppc_md.iommu_save) + ppc_md.iommu_save (); +} + +static inline void iommu_restore (void ) +{ +if (ppc_md.iommu_restore) + ppc_md.iommu_restore (); +} +#endif #endif /* __KERNEL__ */ #endif /* _ASM_IOMMU_H */
include/asm-powerpc/machdep.h +5 -0
@@ -91,6 +91,11 @@ struct machdep_calls {void __iomem * (*ioremap)(phys_addr_t addr,unsigned long size,unsigned long flags);void (*iounmap)(volatile void __iomem *token); + +#ifdef CONFIG_PM +void (*iommu_save)(void ); +void (*iommu_restore)(void ); +#endif #endif /* CONFIG_PPC64 */ int (*probe)(void );
--
RFC 4/6 powerpc: mark pages that dont exist as nosave
In reply to Johannes BergOn some powerpc architectures (notably 64-bit powermac) there is a memory hole, for example on powermacs between 2G and 4G. Since we use the flat memory model regardless, these pages must be marked as nosave (for suspend to disk.)
---
Tested on powerbook and G5 powermac.
--- arch/powerpc/mm/mem.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
arch/powerpc/mm/mem.c +25 -0
@@ -31,6 +31,7 @@#include <linux/highmem.h> #include <linux/initrd.h> #include <linux/pagemap.h> +#include <linux/suspend.h> #include <asm/pgalloc.h> #include <asm/prom.h>
@@ -280,6 +281,28 @@ void __init do_init_bootmem(void) init_bootmem_done =1 ; } +/* mark pages that don't exist as nosave */ +static int __init mark_nonram_nosave (void ) +{ +unsigned long lmb_next_region_start_pfn, + lmb_region_max_pfn; +int i; + +for (i =0 ; i < lmb.memory.cnt -1 ; i++) { + lmb_region_max_pfn = + (lmb.memory.region[i].base >>PAGE_SHIFT ) + + (lmb.memory.region[i].size >>PAGE_SHIFT ); + lmb_next_region_start_pfn = + lmb.memory.region[i+1 ].base >>PAGE_SHIFT ; + +if (lmb_region_max_pfn < lmb_next_region_start_pfn) +register_nosave_region (lmb_region_max_pfn, + lmb_next_region_start_pfn); + } + +return 0 ; +} +/* * paging_init() sets up the page tables - in fact we've already done this. */
@@ -311,6 +334,8 @@ void __init paging_init(void) max_zone_pfns[ZONE_DMA ] = top_of_ram >>PAGE_SHIFT ;#endif free_area_init_nodes (max_zone_pfns); + + mark_nonram_nosave(); }#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
--
RFC 5/6 powermac: fix G5-cpufreq for cpu on/offline
In reply to Johannes BergThe original code here is wrong, it applies "previous" knowledge. The way the cpufreq core is designed is that the policy for the secondary CPU that comes online says that it must in fact not use this policy but use the same as the other CPUs that are listed, which in fact is CPU#0.
--- arch/powerpc/platforms/powermac/cpufreq_64.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/powerpc/platforms/powermac/cpufreq_64.c +4 -4
@@ -357,13 +357,13 @@ static unsigned int g5_cpufreq_get_speedstatic int g5_cpufreq_cpu_init (struct cpufreq_policy *policy) { -if (policy->cpu !=0 ) -return -ENODEV ; - policy->governor =CPUFREQ_DEFAULT_GOVERNOR ; policy->cpuinfo.transition_latency =CPUFREQ_ETERNAL ; policy->cur = g5_cpu_freqs[g5_query_freq ()].frequency; - policy->cpus = cpu_possible_map; +/* secondary CPUs are tied to the primary one by the +* cpufreq core if in the secondary policy we tell it that +* it actually must be one policy together with all others. */ + policy->cpus = cpu_online_map;cpufreq_frequency_table_get_attr (g5_cpu_freqs, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy,
--
RFC 6/6 powermac: suspend to disk on G5
In reply to Johannes BergPowermac G5 suspend to disk implementation. The code is platform agnostic but only tested on powermac, no other 64-bit powerpc machines.
---
WARNING: nvidiafb breaks suspend. I don't know why yet, but if it is compiled and you try to suspend from X it all just freezes. The nvidiafb suspend code looks a bit fishy but I shall have to understand first what it's trying to achieve.
Other than that I'm really happy with this, it's good to finally be able to hibernate the machine instead of keeping it up or shutting it down.
Tested on my powermac, this time with forced preemption enabled, of course only together with all the other patches.
--- arch/powerpc/Kconfig | 5 arch/powerpc/kernel/Makefile | 1 arch/powerpc/kernel/asm-offsets.c | 4 arch/powerpc/kernel/idle.c | 5 arch/powerpc/kernel/swsusp.c | 9 + arch/powerpc/kernel/swsusp_64.c | 24 +++ arch/powerpc/kernel/swsusp_asm64.S | 228 +++++++++++++++++++++++++++++++++++++ include/linux/suspend.h | 2 kernel/power/Kconfig | 4 9 files changed, 276 insertions(+), 6 deletions(-)
arch/powerpc/kernel/Makefile +1 -0
@@ -38,6 +38,7 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6x obj-$(CONFIG_TAU) += tau_6xx.o obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o +obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o obj32-$(CONFIG_MODULES) += module_32.o ifeq ($(CONFIG_PPC_MERGE),y)
kernel/power/Kconfig +2 -2
@@ -91,7 +91,7 @@ config PM_SYSFS_DEPRECATED config SOFTWARE_SUSPEND bool "Software Suspend" - depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) + depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) ---help--- Enable the suspend to disk (STD) functionality.
@@ -146,7 +146,7 @@ config PM_STD_PARTITION config SUSPEND_SMP bool - depends on HOTPLUG_CPU && X86 && PM + depends on HOTPLUG_CPU && (X86 || PPC64) && PM default y config APM_EMULATION
include/linux/suspend.h +1 -1
@@ -1,7 +1,7 @@#ifndef _LINUX_SWSUSP_H#define _LINUX_SWSUSP_H -#if defined(CONFIG_X86 ) || defined(CONFIG_FRV ) || defined(CONFIG_PPC32 ) +#if defined(CONFIG_X86 ) || defined(CONFIG_FRV ) || defined(CONFIG_PPC32 ) || defined(CONFIG_PPC64 )#include <asm/suspend.h> #endif #include <linux/swap.h>
arch/powerpc/kernel/swsusp_64.c new file +24 -0
@@ -0,0 +1,24 @@ +/* +* PowerPC 64-bit swsusp implementation +* +* Copyright 2006 Johannes Berg <[email protected]> +* +* GPLv2 +*/ + +#include <asm/system.h> +#include <asm/iommu.h> +#include <linux/irq.h> +#include <linux/interrupt.h> + +void do_after_copyback (void ) +{ +iommu_restore (); +touch_softlockup_watchdog (); +mb (); +} + +void _iommu_save (void ) +{ +iommu_save (); +}
arch/powerpc/kernel/swsusp_asm64.S new file +228 -0
228 lines not on this page · raw message
arch/powerpc/kernel/asm-offsets.c +2 -2
@@ -21,12 +21,12 @@#include <linux/types.h> #include <linux/mman.h> #include <linux/mm.h> +#include <linux/suspend.h> #ifdef CONFIG_PPC64 #include <linux/time.h> #include <linux/hardirq.h> #else #include <linux/ptrace.h> -#include <linux/suspend.h> #endif #include <asm/io.h>
@@ -257,11 +257,11 @@ int main(void)DEFINE (CPU_SPEC_SETUP , offsetof(struct cpu_spec , cpu_setup));DEFINE (CPU_SPEC_RESTORE , offsetof(struct cpu_spec , cpu_restore)); -#ifndef CONFIG_PPC64 DEFINE (pbe_address, offsetof(struct pbe , address));DEFINE (pbe_orig_address, offsetof(struct pbe , orig_address));DEFINE (pbe_next, offsetof(struct pbe , next)); +#ifndef CONFIG_PPC64 DEFINE (TASK_SIZE ,TASK_SIZE );DEFINE (NUM_USER_SEGMENTS ,TASK_SIZE >>28 );#endif /* ! CONFIG_PPC64 */
arch/powerpc/kernel/idle.c +4 -1
@@ -33,8 +33,11 @@#include <asm/smp.h> #ifdef CONFIG_HOTPLUG_CPU +/* this is used for software suspend, and that shuts down +* CPUs even while the system is still booting... */ #define cpu_should_die () (cpu_is_offline(smp_processor_id()) && \ - system_state == SYSTEM_RUNNING) + (system_state == SYSTEM_RUNNING \ + || system_state == SYSTEM_BOOTING))#else #define cpu_should_die () 0#endif
arch/powerpc/kernel/swsusp.c +9 -0
@@ -32,6 +32,11 @@ void save_processor_state(void)#ifdef CONFIG_SPE enable_kernel_spe ();#endif + +#ifdef CONFIG_PPC64 +hard_irq_disable (); +#endif + }void restore_processor_state (void )
@@ -39,4 +44,8 @@ void restore_processor_state(void)#ifdef CONFIG_PPC32 set_context (current->active_mm->context.id, current->active_mm->pgd);#endif + +#ifdef CONFIG_PPC64 +hard_irq_enable (); +#endif }
arch/powerpc/Kconfig +5 -0
@@ -126,6 +126,11 @@ config DEFAULT_UIMAGE Used to allow a board to specify it wants a uImage built by default default n +config PPC64_SWSUSP + bool + depends on PPC64 && (PPC_PMAC64 || EXPERIMENTAL) + default y + menu "Processor support" choice prompt "Processor Type"
--