0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/cpu_pm.h>
0009 #include <linux/init.h>
0010
0011 #include <asm/dsp.h>
0012 #include <asm/fpu.h>
0013 #include <asm/mmu_context.h>
0014 #include <asm/pm.h>
0015 #include <asm/watch.h>
0016
0017
0018 struct mips_static_suspend_state mips_static_suspend_state;
0019
0020
0021
0022
0023
0024 static int mips_cpu_save(void)
0025 {
0026
0027 lose_fpu(1);
0028
0029
0030 save_dsp(current);
0031
0032 return 0;
0033 }
0034
0035
0036
0037
0038
0039 static void mips_cpu_restore(void)
0040 {
0041 unsigned int cpu = smp_processor_id();
0042
0043
0044 if (current->mm)
0045 write_c0_entryhi(cpu_asid(cpu, current->mm));
0046
0047
0048 restore_dsp(current);
0049
0050
0051 if (cpu_has_userlocal)
0052 write_c0_userlocal(current_thread_info()->tp_value);
0053
0054
0055 __restore_watch(current);
0056 }
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 static int mips_pm_notifier(struct notifier_block *self, unsigned long cmd,
0068 void *v)
0069 {
0070 int ret;
0071
0072 switch (cmd) {
0073 case CPU_PM_ENTER:
0074 ret = mips_cpu_save();
0075 if (ret)
0076 return NOTIFY_STOP;
0077 break;
0078 case CPU_PM_ENTER_FAILED:
0079 case CPU_PM_EXIT:
0080 mips_cpu_restore();
0081 break;
0082 }
0083
0084 return NOTIFY_OK;
0085 }
0086
0087 static struct notifier_block mips_pm_notifier_block = {
0088 .notifier_call = mips_pm_notifier,
0089 };
0090
0091 static int __init mips_pm_init(void)
0092 {
0093 return cpu_pm_register_notifier(&mips_pm_notifier_block);
0094 }
0095 arch_initcall(mips_pm_init);