aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-01-02 18:40:30 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-01-02 18:40:30 -0500
commit8e140362f71ed801c69c5df63a68fc2cd07da3a9 (patch)
tree336c6391cba17d825964ae6a8e19bb5676c9dc59 /arch/arm
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')
-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 e26cc1f59948..490d9d18a7d1 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)
264 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); 264 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
265} 265}
266 266
267static void vfp_enable(void *unused)
268{
269 u32 access = get_copro_access();
270
271 /*
272 * Enable full access to VFP (cp10 and cp11)
273 */
274 set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
275}
276
277#include <linux/smp.h>
278
267/* 279/*
268 * VFP support code initialisation. 280 * VFP support code initialisation.
269 */ 281 */
@@ -288,6 +300,7 @@ static int __init vfp_init(void)
288 * we just need to read the VFPSID register. 300 * we just need to read the VFPSID register.
289 */ 301 */
290 vfpsid = fmrx(FPSID); 302 vfpsid = fmrx(FPSID);
303 barrier();
291 304
292 printk(KERN_INFO "VFP support v0.3: "); 305 printk(KERN_INFO "VFP support v0.3: ");
293 if (VFP_arch) { 306 if (VFP_arch) {
@@ -301,6 +314,8 @@ static int __init vfp_init(void)
301 } else if (vfpsid & FPSID_NODOUBLE) { 314 } else if (vfpsid & FPSID_NODOUBLE) {
302 printk("no double precision support\n"); 315 printk("no double precision support\n");
303 } else { 316 } else {
317 smp_call_function(vfp_enable, NULL, 1, 1);
318
304 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ 319 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
305 printk("implementor %02x architecture %d part %02x variant %x rev %x\n", 320 printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
306 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, 321 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,