ARM: vfp: Use cpu pm notifiers to save vfp state
When the cpu is powered down in a low power mode, the vfp registers may be reset. This patch uses CPU_PM_ENTER and CPU_PM_EXIT notifiers to save and restore the cpu's vfp registers. Signed-off-by: Colin Cross <ccross@android.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Tested-and-Acked-by: Shawn Guo <shawn.guo@linaro.org> Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
This commit is contained in:
parent
254056f3b1
commit
746a9d1963
1 changed files with 21 additions and 8 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
|
#include <linux/cpu_pm.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>
|
||||||
|
@ -436,9 +437,7 @@ static void vfp_enable(void *unused)
|
||||||
set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
|
set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_CPU_PM
|
||||||
#include <linux/syscore_ops.h>
|
|
||||||
|
|
||||||
static int vfp_pm_suspend(void)
|
static int vfp_pm_suspend(void)
|
||||||
{
|
{
|
||||||
struct thread_info *ti = current_thread_info();
|
struct thread_info *ti = current_thread_info();
|
||||||
|
@ -468,19 +467,33 @@ static void vfp_pm_resume(void)
|
||||||
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
|
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct syscore_ops vfp_pm_syscore_ops = {
|
static int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
|
||||||
.suspend = vfp_pm_suspend,
|
void *v)
|
||||||
.resume = vfp_pm_resume,
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case CPU_PM_ENTER:
|
||||||
|
vfp_pm_suspend();
|
||||||
|
break;
|
||||||
|
case CPU_PM_ENTER_FAILED:
|
||||||
|
case CPU_PM_EXIT:
|
||||||
|
vfp_pm_resume();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block vfp_cpu_pm_notifier_block = {
|
||||||
|
.notifier_call = vfp_cpu_pm_notifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vfp_pm_init(void)
|
static void vfp_pm_init(void)
|
||||||
{
|
{
|
||||||
register_syscore_ops(&vfp_pm_syscore_ops);
|
cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline void vfp_pm_init(void) { }
|
static inline void vfp_pm_init(void) { }
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_CPU_PM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that the VFP state stored in 'thread->vfpstate' is up to date
|
* Ensure that the VFP state stored in 'thread->vfpstate' is up to date
|
||||||
|
|
Loading…
Reference in a new issue