diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 22:46:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 22:46:28 -0700 |
commit | 6f3cafce0ed24372084b5648c9e8a6aacbaf9900 (patch) | |
tree | a20de49dbad477a608d1df3ce19f3eeb68417585 /arch/arm/vfp/vfpmodule.c | |
parent | 0c97f524fc16004602f97ba19c36acdcc0fb9688 (diff) | |
parent | 02916526133aebc0b3b6c486d1b0af95221033bd (diff) | |
download | op-kernel-dev-6f3cafce0ed24372084b5648c9e8a6aacbaf9900.zip op-kernel-dev-6f3cafce0ed24372084b5648c9e8a6aacbaf9900.tar.gz |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (21 commits)
[ARM] 3629/1: S3C24XX: fix missing bracket in regs-dsc.h
[ARM] 3537/1: Rework DMA-bounce locking for finer granularity
[ARM] 3601/1: i.MX/MX1 DMA error handling for signaled channels only
[ARM] 3597/1: ixp4xx/nslu2: Board support for new LED subsystem
[ARM] 3595/1: ixp4xx/nas100d: Board support for new LED subsystem
[ARM] 3626/1: ARM EABI: fix syscall restarting
[ARM] 3628/1: S3C24XX: add get_rate call to struct clk
[ARM] 3627/1: S3C24XX: split s3c2410 clocks from core clocks
[ARM] 3613/1: S3C2410: Add sysdev and sysclass
[ARM] 3624/1: Report true modem control line states
[ARM] 3620/2: ixp23xx: add uengine loader support
[ARM] 3618/1: add defconfig for logicpd pxa270 card engine
[ARM] 3617/1: ep93xx: fix slightly incorrect timer tick rate
[ARM] 3616/1: fix timer handler wrap logic for a number of platforms
[ARM] 3615/1: ixp23xx: use platform devices for physmap flash
[ARM] 3614/1: ep93xx: use platform devices for physmap flash
[ARM] 3621/1: fix compilation breakage for pnx4008
[ARM] 3623/1: pnx4008: move GPIO-related defines to gpio.h
[ARM] 3622/1: pnx4008: remove clk_use/clk_unuse
[ARM] Enable VFP to be built when non-VFP capable CPUs are selected
...
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 71 |
1 files changed, 46 insertions, 25 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 03486be..2476f4c 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -15,6 +15,8 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/init.h> + +#include <asm/thread_notify.h> #include <asm/vfp.h> #include "vfpinstr.h" @@ -36,38 +38,55 @@ union vfp_state *last_VFP_context; */ unsigned int VFP_arch; -/* - * Per-thread VFP initialisation. - */ -void vfp_flush_thread(union vfp_state *vfp) +static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { - memset(vfp, 0, sizeof(union vfp_state)); + struct thread_info *thread = v; + union vfp_state *vfp = &thread->vfpstate; - vfp->hard.fpexc = FPEXC_ENABLE; - vfp->hard.fpscr = FPSCR_ROUND_NEAREST; + switch (cmd) { + case THREAD_NOTIFY_FLUSH: + /* + * Per-thread VFP initialisation. + */ + memset(vfp, 0, sizeof(union vfp_state)); - /* - * Disable VFP to ensure we initialise it first. - */ - fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + vfp->hard.fpexc = FPEXC_ENABLE; + vfp->hard.fpscr = FPSCR_ROUND_NEAREST; - /* - * Ensure we don't try to overwrite our newly initialised - * state information on the first fault. - */ - if (last_VFP_context == vfp) - last_VFP_context = NULL; -} + /* + * Disable VFP to ensure we initialise it first. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); -/* - * Per-thread VFP cleanup. - */ -void vfp_release_thread(union vfp_state *vfp) -{ - if (last_VFP_context == vfp) - last_VFP_context = NULL; + /* + * FALLTHROUGH: Ensure we don't try to overwrite our newly + * initialised state information on the first fault. + */ + + case THREAD_NOTIFY_RELEASE: + /* + * Per-thread VFP cleanup. + */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; + break; + + case THREAD_NOTIFY_SWITCH: + /* + * Always disable VFP so we can lazily save/restore the + * old state. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + break; + } + + return NOTIFY_DONE; } +static struct notifier_block vfp_notifier_block = { + .notifier_call = vfp_notifier, +}; + /* * Raise a SIGFPE for the current process. * sicode describes the signal being raised. @@ -281,6 +300,8 @@ static int __init vfp_init(void) (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); vfp_vector = vfp_support_entry; + + thread_register_notifier(&vfp_notifier_block); } return 0; } |