summaryrefslogtreecommitdiffstats
path: root/arch/arm/vfp/vfpmodule.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-01-02 23:40:30 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-01-02 23:40:30 +0000
commit8e140362f71ed801c69c5df63a68fc2cd07da3a9 (patch)
tree336c6391cba17d825964ae6a8e19bb5676c9dc59 /arch/arm/vfp/vfpmodule.c
parent1c9d3df5e88ad7db23f5b22f4341c39722a904a4 (diff)
[ARM] Fix VFP initialisation issue for SMP systems
When we install the handlers for context switching, we must enable VFP on all CPU cores, otherwise undefined (and random) effects occur. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r--arch/arm/vfp/vfpmodule.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index e26cc1f5994..490d9d18a7d 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -264,6 +264,18 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
}
+static void vfp_enable(void *unused)
+{
+ u32 access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+#include <linux/smp.h>
+
/*
* VFP support code initialisation.
*/
@@ -288,6 +300,7 @@ static int __init vfp_init(void)
* we just need to read the VFPSID register.
*/
vfpsid = fmrx(FPSID);
+ barrier();
printk(KERN_INFO "VFP support v0.3: ");
if (VFP_arch) {
@@ -301,6 +314,8 @@ static int __init vfp_init(void)
} else if (vfpsid & FPSID_NODOUBLE) {
printk("no double precision support\n");
} else {
+ smp_call_function(vfp_enable, NULL, 1, 1);
+
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,