aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/vfp/vfpmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r--arch/arm/vfp/vfpmodule.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index bbf3da012afd..f74695075e64 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -78,6 +78,14 @@ static void vfp_thread_exit(struct thread_info *thread)
78 put_cpu(); 78 put_cpu();
79} 79}
80 80
81static void vfp_thread_copy(struct thread_info *thread)
82{
83 struct thread_info *parent = current_thread_info();
84
85 vfp_sync_hwstate(parent);
86 thread->vfpstate = parent->vfpstate;
87}
88
81/* 89/*
82 * When this function is called with the following 'cmd's, the following 90 * When this function is called with the following 'cmd's, the following
83 * is true while this function is being run: 91 * is true while this function is being run:
@@ -104,12 +112,17 @@ static void vfp_thread_exit(struct thread_info *thread)
104static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) 112static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
105{ 113{
106 struct thread_info *thread = v; 114 struct thread_info *thread = v;
115 u32 fpexc;
116#ifdef CONFIG_SMP
117 unsigned int cpu;
118#endif
107 119
108 if (likely(cmd == THREAD_NOTIFY_SWITCH)) { 120 switch (cmd) {
109 u32 fpexc = fmrx(FPEXC); 121 case THREAD_NOTIFY_SWITCH:
122 fpexc = fmrx(FPEXC);
110 123
111#ifdef CONFIG_SMP 124#ifdef CONFIG_SMP
112 unsigned int cpu = thread->cpu; 125 cpu = thread->cpu;
113 126
114 /* 127 /*
115 * On SMP, if VFP is enabled, save the old state in 128 * On SMP, if VFP is enabled, save the old state in
@@ -134,13 +147,20 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
134 * old state. 147 * old state.
135 */ 148 */
136 fmxr(FPEXC, fpexc & ~FPEXC_EN); 149 fmxr(FPEXC, fpexc & ~FPEXC_EN);
137 return NOTIFY_DONE; 150 break;
138 }
139 151
140 if (cmd == THREAD_NOTIFY_FLUSH) 152 case THREAD_NOTIFY_FLUSH:
141 vfp_thread_flush(thread); 153 vfp_thread_flush(thread);
142 else 154 break;
155
156 case THREAD_NOTIFY_EXIT:
143 vfp_thread_exit(thread); 157 vfp_thread_exit(thread);
158 break;
159
160 case THREAD_NOTIFY_COPY:
161 vfp_thread_copy(thread);
162 break;
163 }
144 164
145 return NOTIFY_DONE; 165 return NOTIFY_DONE;
146} 166}