diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-26 01:09:41 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-26 01:09:41 +0300 |
commit | 2741ecb4ce5c2d430b5c44b0a169038338c21df5 (patch) | |
tree | 4aa71d7551184ee88f32c7f3660d821133058c32 /arch/arm/vfp/vfpmodule.c | |
parent | bc85e585c6d0fab4bde12d60964b2f25802c3163 (diff) | |
parent | 5de813b6cd06460b337f9da9afe316823cf3ef45 (diff) | |
download | linux-2741ecb4ce5c2d430b5c44b0a169038338c21df5.tar.xz |
Merge branch 'misc2' into devel
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f60a5400a25b..def19f83d812 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -430,7 +430,11 @@ static inline void vfp_pm_init(void) { } * saved one. This function is used by the ptrace mechanism. */ #ifdef CONFIG_SMP -void vfp_sync_state(struct thread_info *thread) +void vfp_sync_hwstate(struct thread_info *thread) +{ +} + +void vfp_flush_hwstate(struct thread_info *thread) { /* * On SMP systems, the VFP state is automatically saved at every @@ -441,35 +445,48 @@ void vfp_sync_state(struct thread_info *thread) thread->vfpstate.hard.cpu = NR_CPUS; } #else -void vfp_sync_state(struct thread_info *thread) +void vfp_sync_hwstate(struct thread_info *thread) { unsigned int cpu = get_cpu(); - u32 fpexc = fmrx(FPEXC); /* - * If VFP is enabled, the previous state was already saved and - * last_VFP_context updated. + * If the thread we're interested in is the current owner of the + * hardware VFP state, then we need to save its state. */ - if (fpexc & FPEXC_EN) - goto out; + if (last_VFP_context[cpu] == &thread->vfpstate) { + u32 fpexc = fmrx(FPEXC); - if (!last_VFP_context[cpu]) - goto out; + /* + * Save the last VFP state on this CPU. + */ + fmxr(FPEXC, fpexc | FPEXC_EN); + vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN); + fmxr(FPEXC, fpexc); + } - /* - * Save the last VFP state on this CPU. - */ - fmxr(FPEXC, fpexc | FPEXC_EN); - vfp_save_state(last_VFP_context[cpu], fpexc); - fmxr(FPEXC, fpexc); + put_cpu(); +} + +void vfp_flush_hwstate(struct thread_info *thread) +{ + unsigned int cpu = get_cpu(); /* - * Set the context to NULL to force a reload the next time the thread - * uses the VFP. + * If the thread we're interested in is the current owner of the + * hardware VFP state, then we need to save its state. */ - last_VFP_context[cpu] = NULL; + if (last_VFP_context[cpu] == &thread->vfpstate) { + u32 fpexc = fmrx(FPEXC); + + fmxr(FPEXC, fpexc & ~FPEXC_EN); + + /* + * Set the context to NULL to force a reload the next time + * the thread uses the VFP. + */ + last_VFP_context[cpu] = NULL; + } -out: put_cpu(); } #endif |