Merge branch 'drm-fixes-5.2' of git://people.freedesktop.org/~agd5f/linux into drm...
[sfrench/cifs-2.6.git] / arch / riscv / include / asm / switch_to.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 Regents of the University of California
4  */
5
6 #ifndef _ASM_RISCV_SWITCH_TO_H
7 #define _ASM_RISCV_SWITCH_TO_H
8
9 #include <asm/processor.h>
10 #include <asm/ptrace.h>
11 #include <asm/csr.h>
12
13 #ifdef CONFIG_FPU
14 extern void __fstate_save(struct task_struct *save_to);
15 extern void __fstate_restore(struct task_struct *restore_from);
16
17 static inline void __fstate_clean(struct pt_regs *regs)
18 {
19         regs->sstatus |= (regs->sstatus & ~(SR_FS)) | SR_FS_CLEAN;
20 }
21
22 static inline void fstate_save(struct task_struct *task,
23                                struct pt_regs *regs)
24 {
25         if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
26                 __fstate_save(task);
27                 __fstate_clean(regs);
28         }
29 }
30
31 static inline void fstate_restore(struct task_struct *task,
32                                   struct pt_regs *regs)
33 {
34         if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
35                 __fstate_restore(task);
36                 __fstate_clean(regs);
37         }
38 }
39
40 static inline void __switch_to_aux(struct task_struct *prev,
41                                    struct task_struct *next)
42 {
43         struct pt_regs *regs;
44
45         regs = task_pt_regs(prev);
46         if (unlikely(regs->sstatus & SR_SD))
47                 fstate_save(prev, regs);
48         fstate_restore(next, task_pt_regs(next));
49 }
50
51 extern bool has_fpu;
52 #else
53 #define has_fpu false
54 #define fstate_save(task, regs) do { } while (0)
55 #define fstate_restore(task, regs) do { } while (0)
56 #define __switch_to_aux(__prev, __next) do { } while (0)
57 #endif
58
59 extern struct task_struct *__switch_to(struct task_struct *,
60                                        struct task_struct *);
61
62 #define switch_to(prev, next, last)                     \
63 do {                                                    \
64         struct task_struct *__prev = (prev);            \
65         struct task_struct *__next = (next);            \
66         if (has_fpu)                                    \
67                 __switch_to_aux(__prev, __next);        \
68         ((last) = __switch_to(__prev, __next));         \
69 } while (0)
70
71 #endif /* _ASM_RISCV_SWITCH_TO_H */