diff options
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index bc683b8219b5..b0197b2c857d 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/cpu.h> | 12 | #include <linux/cpu.h> |
13 | #include <linux/cpu_pm.h> | 13 | #include <linux/cpu_pm.h> |
14 | #include <linux/hardirq.h> | ||
14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
15 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
16 | #include <linux/signal.h> | 17 | #include <linux/signal.h> |
@@ -432,7 +433,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
432 | 433 | ||
433 | static void vfp_enable(void *unused) | 434 | static void vfp_enable(void *unused) |
434 | { | 435 | { |
435 | u32 access = get_copro_access(); | 436 | u32 access; |
437 | |||
438 | BUG_ON(preemptible()); | ||
439 | access = get_copro_access(); | ||
436 | 440 | ||
437 | /* | 441 | /* |
438 | * Enable full access to VFP (cp10 and cp11) | 442 | * Enable full access to VFP (cp10 and cp11) |
@@ -573,12 +577,6 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, | |||
573 | * entry. | 577 | * entry. |
574 | */ | 578 | */ |
575 | hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); | 579 | hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); |
576 | |||
577 | /* | ||
578 | * Disable VFP in the hwstate so that we can detect if it gets | ||
579 | * used. | ||
580 | */ | ||
581 | hwstate->fpexc &= ~FPEXC_EN; | ||
582 | return 0; | 580 | return 0; |
583 | } | 581 | } |
584 | 582 | ||
@@ -591,12 +589,8 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp, | |||
591 | unsigned long fpexc; | 589 | unsigned long fpexc; |
592 | int err = 0; | 590 | int err = 0; |
593 | 591 | ||
594 | /* | 592 | /* Disable VFP to avoid corrupting the new thread state. */ |
595 | * If VFP has been used, then disable it to avoid corrupting | 593 | vfp_flush_hwstate(thread); |
596 | * the new thread state. | ||
597 | */ | ||
598 | if (hwstate->fpexc & FPEXC_EN) | ||
599 | vfp_flush_hwstate(thread); | ||
600 | 594 | ||
601 | /* | 595 | /* |
602 | * Copy the floating point registers. There can be unused | 596 | * Copy the floating point registers. There can be unused |
@@ -657,7 +651,7 @@ static int __init vfp_init(void) | |||
657 | unsigned int cpu_arch = cpu_architecture(); | 651 | unsigned int cpu_arch = cpu_architecture(); |
658 | 652 | ||
659 | if (cpu_arch >= CPU_ARCH_ARMv6) | 653 | if (cpu_arch >= CPU_ARCH_ARMv6) |
660 | vfp_enable(NULL); | 654 | on_each_cpu(vfp_enable, NULL, 1); |
661 | 655 | ||
662 | /* | 656 | /* |
663 | * First check that there is a VFP that we can use. | 657 | * First check that there is a VFP that we can use. |
@@ -678,8 +672,6 @@ static int __init vfp_init(void) | |||
678 | } else { | 672 | } else { |
679 | hotcpu_notifier(vfp_hotplug, 0); | 673 | hotcpu_notifier(vfp_hotplug, 0); |
680 | 674 | ||
681 | smp_call_function(vfp_enable, NULL, 1); | ||
682 | |||
683 | VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ | 675 | VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ |
684 | printk("implementor %02x architecture %d part %02x variant %x rev %x\n", | 676 | printk("implementor %02x architecture %d part %02x variant %x rev %x\n", |
685 | (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, | 677 | (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, |