Pull asus into release branch
[pandora-kernel.git] / include / asm-mips / fpu.h
index 58c561a..b414a7d 100644 (file)
 struct sigcontext;
 struct sigcontext32;
 
-extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
-extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
 
-extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc);
-extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc);
+extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
+extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 
 extern void fpu_emulator_init_fpu(void);
 extern void _init_fpu(void);
@@ -93,31 +93,52 @@ static inline int is_fpu_owner(void)
        return cpu_has_fpu && __is_fpu_owner();
 }
 
-static inline void own_fpu(void)
+static inline void __own_fpu(void)
 {
-       if (cpu_has_fpu) {
-               __enable_fpu();
-               KSTK_STATUS(current) |= ST0_CU1;
-               set_thread_flag(TIF_USEDFPU);
+       __enable_fpu();
+       KSTK_STATUS(current) |= ST0_CU1;
+       set_thread_flag(TIF_USEDFPU);
+}
+
+static inline void own_fpu_inatomic(int restore)
+{
+       if (cpu_has_fpu && !__is_fpu_owner()) {
+               __own_fpu();
+               if (restore)
+                       _restore_fp(current);
        }
 }
 
-static inline void lose_fpu(void)
+static inline void own_fpu(int restore)
 {
-       if (cpu_has_fpu) {
+       preempt_disable();
+       own_fpu_inatomic(restore);
+       preempt_enable();
+}
+
+static inline void lose_fpu(int save)
+{
+       preempt_disable();
+       if (is_fpu_owner()) {
+               if (save)
+                       _save_fp(current);
                KSTK_STATUS(current) &= ~ST0_CU1;
                clear_thread_flag(TIF_USEDFPU);
                __disable_fpu();
        }
+       preempt_enable();
 }
 
 static inline void init_fpu(void)
 {
+       preempt_disable();
        if (cpu_has_fpu) {
+               __own_fpu();
                _init_fpu();
        } else {
                fpu_emulator_init_fpu();
        }
+       preempt_enable();
 }
 
 static inline void save_fp(struct task_struct *tsk)
@@ -134,9 +155,11 @@ static inline void restore_fp(struct task_struct *tsk)
 
 static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
 {
-       if (cpu_has_fpu) {
-               if ((tsk == current) && __is_fpu_owner())
+       if (tsk == current) {
+               preempt_disable();
+               if (is_fpu_owner())
                        _save_fp(current);
+               preempt_enable();
        }
 
        return tsk->thread.fpu.fpr;