ARM: vfp: Use cpu pm notifiers to save vfp state
Colin Cross [Thu, 10 Feb 2011 10:08:32 +0000 (02:08 -0800)]
Signed-off-by: Colin Cross <ccross@android.com>

arch/arm/vfp/vfpmodule.c

index 79bcb43..e5a857a 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/cputype.h>
 #include <asm/thread_notify.h>
 #include <asm/vfp.h>
+#include <asm/cpu_pm.h>
 
 #include "vfpinstr.h"
 #include "vfp.h"
@@ -208,6 +209,35 @@ static struct notifier_block vfp_notifier_block = {
        .notifier_call  = vfp_notifier,
 };
 
+static int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
+       void *v)
+{
+       u32 fpexc = fmrx(FPEXC);
+       unsigned int cpu = smp_processor_id();
+
+       switch (cmd) {
+       case CPU_PM_ENTER:
+               if (last_VFP_context[cpu]) {
+                       fmxr(FPEXC, fpexc | FPEXC_EN);
+                       vfp_save_state(last_VFP_context[cpu], fpexc);
+                       /* force a reload when coming back from idle */
+                       last_VFP_context[cpu] = NULL;
+                       fmxr(FPEXC, fpexc & ~FPEXC_EN);
+               }
+               break;
+       case CPU_PM_ENTER_FAILED:
+       case CPU_PM_EXIT:
+               /* make sure VFP is disabled when leaving idle */
+               fmxr(FPEXC, fpexc & ~FPEXC_EN);
+               break;
+       }
+       return NOTIFY_OK;
+}
+
+static struct notifier_block vfp_cpu_pm_notifier_block = {
+       .notifier_call = vfp_cpu_pm_notifier,
+};
+
 /*
  * Raise a SIGFPE for the current process.
  * sicode describes the signal being raised.
@@ -578,6 +608,7 @@ static int __init vfp_init(void)
                vfp_vector = vfp_support_entry;
 
                thread_register_notifier(&vfp_notifier_block);
+               cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block);
                vfp_pm_init();
 
                /*