|
@@ -11,6 +11,7 @@
|
|
#include <linux/types.h>
|
|
#include <linux/types.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cpu_pm.h>
|
|
#include <linux/cpu_pm.h>
|
|
|
|
+#include <linux/hardirq.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/signal.h>
|
|
@@ -432,7 +433,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
|
|
|
|
|
|
static void vfp_enable(void *unused)
|
|
static void vfp_enable(void *unused)
|
|
{
|
|
{
|
|
- u32 access = get_copro_access();
|
|
|
|
|
|
+ u32 access;
|
|
|
|
+
|
|
|
|
+ BUG_ON(preemptible());
|
|
|
|
+ access = get_copro_access();
|
|
|
|
|
|
/*
|
|
/*
|
|
* Enable full access to VFP (cp10 and cp11)
|
|
* Enable full access to VFP (cp10 and cp11)
|
|
@@ -573,12 +577,6 @@ int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
|
|
* entry.
|
|
* entry.
|
|
*/
|
|
*/
|
|
hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
|
|
hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Disable VFP in the hwstate so that we can detect if it gets
|
|
|
|
- * used.
|
|
|
|
- */
|
|
|
|
- hwstate->fpexc &= ~FPEXC_EN;
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -591,12 +589,8 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
|
|
unsigned long fpexc;
|
|
unsigned long fpexc;
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
- /*
|
|
|
|
- * If VFP has been used, then disable it to avoid corrupting
|
|
|
|
- * the new thread state.
|
|
|
|
- */
|
|
|
|
- if (hwstate->fpexc & FPEXC_EN)
|
|
|
|
- vfp_flush_hwstate(thread);
|
|
|
|
|
|
+ /* Disable VFP to avoid corrupting the new thread state. */
|
|
|
|
+ vfp_flush_hwstate(thread);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Copy the floating point registers. There can be unused
|
|
* Copy the floating point registers. There can be unused
|
|
@@ -657,7 +651,7 @@ static int __init vfp_init(void)
|
|
unsigned int cpu_arch = cpu_architecture();
|
|
unsigned int cpu_arch = cpu_architecture();
|
|
|
|
|
|
if (cpu_arch >= CPU_ARCH_ARMv6)
|
|
if (cpu_arch >= CPU_ARCH_ARMv6)
|
|
- vfp_enable(NULL);
|
|
|
|
|
|
+ on_each_cpu(vfp_enable, NULL, 1);
|
|
|
|
|
|
/*
|
|
/*
|
|
* First check that there is a VFP that we can use.
|
|
* First check that there is a VFP that we can use.
|
|
@@ -678,8 +672,6 @@ static int __init vfp_init(void)
|
|
} else {
|
|
} else {
|
|
hotcpu_notifier(vfp_hotplug, 0);
|
|
hotcpu_notifier(vfp_hotplug, 0);
|
|
|
|
|
|
- smp_call_function(vfp_enable, NULL, 1);
|
|
|
|
-
|
|
|
|
VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
|
|
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",
|
|
printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
|
|
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
|
|
(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
|