2 * ARM Cortex-A7 save/restore for suspend to disk (Hibernation)
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/init.h>
7 #include <linux/types.h>
8 #include <linux/spinlock.h>
9 #include <linux/poll.h>
10 #include <linux/delay.h>
11 #include <linux/sysrq.h>
12 #include <linux/proc_fs.h>
14 #include <linux/device.h>
15 #include <linux/suspend.h>
17 #include <asm/uaccess.h>
18 #include <asm/tlbflush.h>
19 #include <asm/suspend.h>
21 extern asmlinkage
void save_cp15(void *pointer
);
22 extern asmlinkage
void save_control_registers(void *pointer
, int is_secure
);
23 extern asmlinkage
void save_mmu(void *pointer
);
24 extern asmlinkage
void save_fault_status(void *pointer
);
25 extern asmlinkage
void save_generic_timer(void *pointer
, int is_hyp
);
26 extern asmlinkage
void restore_control_registers(void *pointer
, int is_secure
);
27 extern asmlinkage
void restore_cp15(void *pointer
);
28 extern asmlinkage
void restore_mmu(void *pointer
);
29 extern asmlinkage
void restore_fault_status(void *pointer
);
30 extern asmlinkage
void restore_generic_timer(void *pointer
, int is_hyp
);
32 extern void trace_stop_dormant(void);
33 extern void trace_start_dormant(void);
36 typedef struct fault_regs
{
45 typedef struct ns_banked_cp15_context
{
46 unsigned int cp15_misc_regs
[2]; /* cp15 miscellaneous registers */
47 unsigned int cp15_ctrl_regs
[20]; /* cp15 control registers */
48 unsigned int cp15_mmu_regs
[16]; /* cp15 mmu registers */
49 cp15_fault_regs ns_cp15_fault_regs
; /* cp15 fault status registers */
50 } banked_cp15_context
;
52 typedef struct gen_tmr_ctx
{
54 unsigned long long cntvoff
;
57 unsigned long long cntp_cval
;
60 unsigned long long cntv_cval
;
63 unsigned long long cnthp_cval
;
66 } generic_timer_context
;
69 static banked_cp15_context saved_cp15_context
;
70 static generic_timer_context saved_cp15_timer_ctx
;
72 static void __save_processor_state(struct ns_banked_cp15_context
*ctxt
)
74 /* save preempt state and disable it */
77 // The 32-bit Generic timer context
78 save_generic_timer(&saved_cp15_timer_ctx
, 0x0);
80 save_cp15(ctxt
->cp15_misc_regs
);
81 save_control_registers(ctxt
->cp15_ctrl_regs
, 0x0);
82 save_mmu(ctxt
->cp15_mmu_regs
);
83 save_fault_status(&ctxt
->ns_cp15_fault_regs
);
86 void save_processor_state(void)
88 __save_processor_state(&saved_cp15_context
);
91 static void __restore_processor_state(struct ns_banked_cp15_context
*ctxt
)
93 restore_fault_status(&ctxt
->ns_cp15_fault_regs
);
94 restore_mmu(ctxt
->cp15_mmu_regs
);
95 restore_control_registers(ctxt
->cp15_ctrl_regs
, 0x0);
96 restore_cp15(ctxt
->cp15_misc_regs
);
98 // The 32-bit Generic timer context
99 restore_generic_timer(&saved_cp15_timer_ctx
, 0x0);
101 // restore ETM module
102 #ifdef CONFIG_MTK_ETM
103 trace_stop_dormant();
104 trace_start_dormant();
106 /* restore preempt state */
110 void restore_processor_state(void)
112 __restore_processor_state(&saved_cp15_context
);
115 EXPORT_SYMBOL(save_processor_state
);
116 EXPORT_SYMBOL(restore_processor_state
);
117 extern const void __nosave_begin
, __nosave_end
;
119 int pfn_is_nosave(unsigned long pfn
)
121 unsigned long begin_pfn
= __pa(&__nosave_begin
) >> PAGE_SHIFT
;
122 unsigned long end_pfn
= PAGE_ALIGN(__pa(&__nosave_end
)) >> PAGE_SHIFT
;
124 return (pfn
>= begin_pfn
) && (pfn
< end_pfn
);