diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-01-02 18:40:30 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-01-02 18:40:30 -0500 |
commit | 8e140362f71ed801c69c5df63a68fc2cd07da3a9 (patch) | |
tree | 336c6391cba17d825964ae6a8e19bb5676c9dc59 /arch/arm/vfp | |
parent | 1c9d3df5e88ad7db23f5b22f4341c39722a904a4 (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')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 15 |
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 | ||
267 | static 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, |