#define COMMON_USER_BOOKE      (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
                                 PPC_FEATURE_BOOKE)
 
-/* We only set the spe features if the kernel was compiled with
- * spe support
- */
-#ifdef CONFIG_SPE
-#define PPC_FEATURE_SPE_COMP   PPC_FEATURE_HAS_SPE
-#else
-#define PPC_FEATURE_SPE_COMP   0
-#endif
-
 static struct cpu_spec cpu_specs[] = {
 #ifdef CONFIG_PPC64
        {       /* Power3 */
                /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
                .cpu_features           = CPU_FTRS_E200,
                .cpu_user_features      = COMMON_USER_BOOKE |
-                       PPC_FEATURE_SPE_COMP |
-                       PPC_FEATURE_HAS_EFP_SINGLE |
+                       PPC_FEATURE_HAS_SPE_COMP |
+                       PPC_FEATURE_HAS_EFP_SINGLE_COMP |
                        PPC_FEATURE_UNIFIED_CACHE,
                .dcache_bsize           = 32,
                .platform               = "ppc5554",
                /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
                .cpu_features           = CPU_FTRS_E500,
                .cpu_user_features      = COMMON_USER_BOOKE |
-                       PPC_FEATURE_SPE_COMP |
-                       PPC_FEATURE_HAS_EFP_SINGLE,
+                       PPC_FEATURE_HAS_SPE_COMP |
+                       PPC_FEATURE_HAS_EFP_SINGLE_COMP,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
                /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
                .cpu_features           = CPU_FTRS_E500_2,
                .cpu_user_features      = COMMON_USER_BOOKE |
-                       PPC_FEATURE_SPE_COMP |
-                       PPC_FEATURE_HAS_EFP_SINGLE |
-                       PPC_FEATURE_HAS_EFP_DOUBLE,
+                       PPC_FEATURE_HAS_SPE_COMP |
+                       PPC_FEATURE_HAS_EFP_SINGLE_COMP |
+                       PPC_FEATURE_HAS_EFP_DOUBLE_COMP,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
 
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_SPE
+BEGIN_FTR_SECTION
        oris    r0,r0,MSR_SPE@h  /* Disable SPE */
        mfspr   r12,SPRN_SPEFSCR /* save spefscr register value */
        stw     r12,THREAD+THREAD_SPEFSCR(r2)
+END_FTR_SECTION_IFSET(CPU_FTR_SPE)
 #endif /* CONFIG_SPE */
        and.    r0,r0,r11       /* FP or altivec or SPE enabled? */
        beq+    1f
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_SPE
+BEGIN_FTR_SECTION
        lwz     r0,THREAD+THREAD_SPEFSCR(r2)
        mtspr   SPRN_SPEFSCR,r0         /* restore SPEFSCR reg */
+END_FTR_SECTION_IFSET(CPU_FTR_SPE)
 #endif /* CONFIG_SPE */
 
        lwz     r0,_CCR(r1)
 
         * mode (asyn, precise, disabled) for 'Classic' FP. */
        if (val & PR_FP_EXC_SW_ENABLE) {
 #ifdef CONFIG_SPE
-               tsk->thread.fpexc_mode = val &
-                       (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
-               return 0;
+               if (cpu_has_feature(CPU_FTR_SPE)) {
+                       tsk->thread.fpexc_mode = val &
+                               (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
+                       return 0;
+               } else {
+                       return -EINVAL;
+               }
 #else
                return -EINVAL;
 #endif
 
        if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
 #ifdef CONFIG_SPE
-               val = tsk->thread.fpexc_mode;
+               if (cpu_has_feature(CPU_FTR_SPE))
+                       val = tsk->thread.fpexc_mode;
+               else
+                       return -EINVAL;
 #else
                return -EINVAL;
 #endif
 
 #ifdef CONFIG_SPE
        case PTRACE_GETEVRREGS:
                /* Get the child spe register state. */
-               if (child->thread.regs->msr & MSR_SPE)
-                       giveup_spe(child);
+               flush_spe_to_thread(child);
                ret = get_evrregs((unsigned long __user *)data, child);
                break;
 
                /* Set the child spe register state. */
                /* this is to clear the MSR_SPE bit to force a reload
                 * of register state from memory */
-               if (child->thread.regs->msr & MSR_SPE)
-                       giveup_spe(child);
+               flush_spe_to_thread(child);
                ret = set_evrregs(child, (unsigned long __user *)data);
                break;
 #endif
 
 #define CPU_FTR_REAL_LE                        ASM_CONST(0x0000000000400000)
 #define CPU_FTR_FPU_UNAVAILABLE                ASM_CONST(0x0000000000800000)
 #define CPU_FTR_UNIFIED_ID_CACHE       ASM_CONST(0x0000000001000000)
+#define CPU_FTR_SPE                    ASM_CONST(0x0000000002000000)
 
 /*
  * Add the 64-bit processor unique features in the top half of the word;
 #define PPC_FEATURE_HAS_ALTIVEC_COMP    0
 #endif
 
+/* We only set the spe features if the kernel was compiled with spe
+ * support
+ */
+#ifdef CONFIG_SPE
+#define CPU_FTR_SPE_COMP       CPU_FTR_SPE
+#define PPC_FEATURE_HAS_SPE_COMP PPC_FEATURE_HAS_SPE
+#define PPC_FEATURE_HAS_EFP_SINGLE_COMP PPC_FEATURE_HAS_EFP_SINGLE
+#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP PPC_FEATURE_HAS_EFP_DOUBLE
+#else
+#define CPU_FTR_SPE_COMP       0
+#define PPC_FEATURE_HAS_SPE_COMP    0
+#define PPC_FEATURE_HAS_EFP_SINGLE_COMP 0
+#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP 0
+#endif
+
 /* We need to mark all pages as being coherent if we're SMP or we
  * have a 74[45]x and an MPC107 host bridge. Also 83xx requires
  * it for PCI "streaming/prefetch" to work properly.
 #define CPU_FTRS_8XX   (CPU_FTR_USE_TB)
 #define CPU_FTRS_40X   (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
 #define CPU_FTRS_44X   (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
-#define CPU_FTRS_E200  (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
-           CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE)
-#define CPU_FTRS_E500  (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
-#define CPU_FTRS_E500_2        (CPU_FTR_USE_TB | \
+#define CPU_FTRS_E200  (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
+           CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
+           CPU_FTR_UNIFIED_ID_CACHE)
+#define CPU_FTRS_E500  (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
+           CPU_FTR_NODSISRALIGN)
+#define CPU_FTRS_E500_2        (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
            CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN)
 #define CPU_FTRS_GENERIC_32    (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)