diff options
Diffstat (limited to 'arch/mn10300/include/asm/system.h')
-rw-r--r-- | arch/mn10300/include/asm/system.h | 73 |
1 files changed, 22 insertions, 51 deletions
diff --git a/arch/mn10300/include/asm/system.h b/arch/mn10300/include/asm/system.h index 9f7c7e17c01e..8ff3e5aaca41 100644 --- a/arch/mn10300/include/asm/system.h +++ b/arch/mn10300/include/asm/system.h | |||
@@ -12,12 +12,29 @@ | |||
12 | #define _ASM_SYSTEM_H | 12 | #define _ASM_SYSTEM_H |
13 | 13 | ||
14 | #include <asm/cpu-regs.h> | 14 | #include <asm/cpu-regs.h> |
15 | #include <asm/intctl-regs.h> | ||
15 | 16 | ||
16 | #ifdef __KERNEL__ | 17 | #ifdef __KERNEL__ |
17 | #ifndef __ASSEMBLY__ | 18 | #ifndef __ASSEMBLY__ |
18 | 19 | ||
19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
20 | #include <linux/irqflags.h> | 21 | #include <linux/irqflags.h> |
22 | #include <asm/atomic.h> | ||
23 | |||
24 | #if !defined(CONFIG_LAZY_SAVE_FPU) | ||
25 | struct fpu_state_struct; | ||
26 | extern asmlinkage void fpu_save(struct fpu_state_struct *); | ||
27 | #define switch_fpu(prev, next) \ | ||
28 | do { \ | ||
29 | if ((prev)->thread.fpu_flags & THREAD_HAS_FPU) { \ | ||
30 | (prev)->thread.fpu_flags &= ~THREAD_HAS_FPU; \ | ||
31 | (prev)->thread.uregs->epsw &= ~EPSW_FE; \ | ||
32 | fpu_save(&(prev)->thread.fpu_state); \ | ||
33 | } \ | ||
34 | } while (0) | ||
35 | #else | ||
36 | #define switch_fpu(prev, next) do {} while (0) | ||
37 | #endif | ||
21 | 38 | ||
22 | struct task_struct; | 39 | struct task_struct; |
23 | struct thread_struct; | 40 | struct thread_struct; |
@@ -30,6 +47,7 @@ struct task_struct *__switch_to(struct thread_struct *prev, | |||
30 | /* context switching is now performed out-of-line in switch_to.S */ | 47 | /* context switching is now performed out-of-line in switch_to.S */ |
31 | #define switch_to(prev, next, last) \ | 48 | #define switch_to(prev, next, last) \ |
32 | do { \ | 49 | do { \ |
50 | switch_fpu(prev, next); \ | ||
33 | current->thread.wchan = (u_long) __builtin_return_address(0); \ | 51 | current->thread.wchan = (u_long) __builtin_return_address(0); \ |
34 | (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \ | 52 | (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \ |
35 | mb(); \ | 53 | mb(); \ |
@@ -40,8 +58,6 @@ do { \ | |||
40 | 58 | ||
41 | #define nop() asm volatile ("nop") | 59 | #define nop() asm volatile ("nop") |
42 | 60 | ||
43 | #endif /* !__ASSEMBLY__ */ | ||
44 | |||
45 | /* | 61 | /* |
46 | * Force strict CPU ordering. | 62 | * Force strict CPU ordering. |
47 | * And yes, this is required on UP too when we're talking | 63 | * And yes, this is required on UP too when we're talking |
@@ -68,64 +84,19 @@ do { \ | |||
68 | #define smp_mb() mb() | 84 | #define smp_mb() mb() |
69 | #define smp_rmb() rmb() | 85 | #define smp_rmb() rmb() |
70 | #define smp_wmb() wmb() | 86 | #define smp_wmb() wmb() |
71 | #else | 87 | #define set_mb(var, value) do { xchg(&var, value); } while (0) |
88 | #else /* CONFIG_SMP */ | ||
72 | #define smp_mb() barrier() | 89 | #define smp_mb() barrier() |
73 | #define smp_rmb() barrier() | 90 | #define smp_rmb() barrier() |
74 | #define smp_wmb() barrier() | 91 | #define smp_wmb() barrier() |
75 | #endif | ||
76 | |||
77 | #define set_mb(var, value) do { var = value; mb(); } while (0) | 92 | #define set_mb(var, value) do { var = value; mb(); } while (0) |
93 | #endif /* CONFIG_SMP */ | ||
94 | |||
78 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) | 95 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) |
79 | 96 | ||
80 | #define read_barrier_depends() do {} while (0) | 97 | #define read_barrier_depends() do {} while (0) |
81 | #define smp_read_barrier_depends() do {} while (0) | 98 | #define smp_read_barrier_depends() do {} while (0) |
82 | 99 | ||
83 | /*****************************************************************************/ | ||
84 | /* | ||
85 | * MN10300 doesn't actually have an exchange instruction | ||
86 | */ | ||
87 | #ifndef __ASSEMBLY__ | ||
88 | |||
89 | struct __xchg_dummy { unsigned long a[100]; }; | ||
90 | #define __xg(x) ((struct __xchg_dummy *)(x)) | ||
91 | |||
92 | static inline | ||
93 | unsigned long __xchg(volatile unsigned long *m, unsigned long val) | ||
94 | { | ||
95 | unsigned long retval; | ||
96 | unsigned long flags; | ||
97 | |||
98 | local_irq_save(flags); | ||
99 | retval = *m; | ||
100 | *m = val; | ||
101 | local_irq_restore(flags); | ||
102 | return retval; | ||
103 | } | ||
104 | |||
105 | #define xchg(ptr, v) \ | ||
106 | ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \ | ||
107 | (unsigned long)(v))) | ||
108 | |||
109 | static inline unsigned long __cmpxchg(volatile unsigned long *m, | ||
110 | unsigned long old, unsigned long new) | ||
111 | { | ||
112 | unsigned long retval; | ||
113 | unsigned long flags; | ||
114 | |||
115 | local_irq_save(flags); | ||
116 | retval = *m; | ||
117 | if (retval == old) | ||
118 | *m = new; | ||
119 | local_irq_restore(flags); | ||
120 | return retval; | ||
121 | } | ||
122 | |||
123 | #define cmpxchg(ptr, o, n) \ | ||
124 | ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \ | ||
125 | (unsigned long)(o), \ | ||
126 | (unsigned long)(n))) | ||
127 | |||
128 | #endif /* !__ASSEMBLY__ */ | 100 | #endif /* !__ASSEMBLY__ */ |
129 | |||
130 | #endif /* __KERNEL__ */ | 101 | #endif /* __KERNEL__ */ |
131 | #endif /* _ASM_SYSTEM_H */ | 102 | #endif /* _ASM_SYSTEM_H */ |