Merge branch 'mips-for-linux-next' of git://git.linux-mips.org/pub/scm/ralf/upstream-sfr
[linux.git] / arch / mips / include / asm / switch_to.h
index 278d45a097286034bfba656c9d626b1ff3d810b2..495c1041a2cc24e3ca1207ac31e7e3ff41f45382 100644 (file)
 #include <asm/watch.h>
 #include <asm/dsp.h>
 #include <asm/cop2.h>
+#include <asm/msa.h>
 
 struct task_struct;
 
+enum {
+       FP_SAVE_NONE    = 0,
+       FP_SAVE_VECTOR  = -1,
+       FP_SAVE_SCALAR  = 1,
+};
+
 /**
  * resume - resume execution of a task
  * @prev:      The task previously executed.
  * @next:      The task to begin executing.
  * @next_ti:   task_thread_info(next).
- * @usedfpu:   Non-zero if prev's FP context should be saved.
+ * @fp_save:   Which, if any, FP context to save for prev.
  *
  * This function is used whilst scheduling to save the context of prev & load
  * the context of next. Returns prev.
  */
 extern asmlinkage struct task_struct *resume(struct task_struct *prev,
                struct task_struct *next, struct thread_info *next_ti,
-               u32 usedfpu);
+               s32 fp_save);
 
 extern unsigned int ll_bit;
 extern struct task_struct *ll_task;
@@ -75,7 +82,8 @@ do {                                                                  \
 
 #define switch_to(prev, next, last)                                    \
 do {                                                                   \
-       u32 __usedfpu, __c0_stat;                                       \
+       u32 __c0_stat;                                                  \
+       s32 __fpsave = FP_SAVE_NONE;                                    \
        __mips_mt_fpaff_switch_to(prev);                                \
        if (cpu_has_dsp)                                                \
                __save_dsp(prev);                                       \
@@ -88,8 +96,12 @@ do {                                                                 \
                write_c0_status(__c0_stat & ~ST0_CU2);                  \
        }                                                               \
        __clear_software_ll_bit();                                      \
-       __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU);  \
-       (last) = resume(prev, next, task_thread_info(next), __usedfpu); \
+       if (test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU))          \
+               __fpsave = FP_SAVE_SCALAR;                              \
+       if (test_and_clear_tsk_thread_flag(prev, TIF_USEDMSA))          \
+               __fpsave = FP_SAVE_VECTOR;                              \
+       (last) = resume(prev, next, task_thread_info(next), __fpsave);  \
+       disable_msa();                                                  \
 } while (0)
 
 #define finish_arch_switch(prev)                                       \