import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / cpu_hibernate.c
1 /*
2 * ARM Cortex-A7 save/restore for suspend to disk (Hibernation)
3 */
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>
13 #include <linux/pm.h>
14 #include <linux/device.h>
15 #include <linux/suspend.h>
16 #include <asm/irq.h>
17 #include <asm/uaccess.h>
18 #include <asm/tlbflush.h>
19 #include <asm/suspend.h>
20
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);
31 #ifdef CONFIG_MTK_ETM
32 extern void trace_stop_dormant(void);
33 extern void trace_start_dormant(void);
34 #endif
35
36 typedef struct fault_regs {
37 unsigned dfar;
38 unsigned ifar;
39 unsigned ifsr;
40 unsigned dfsr;
41 unsigned adfsr;
42 unsigned aifsr;
43 } cp15_fault_regs;
44
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;
51
52 typedef struct gen_tmr_ctx {
53 unsigned cntfrq;
54 unsigned long long cntvoff;
55 unsigned cnthctl;
56 unsigned cntkctl;
57 unsigned long long cntp_cval;
58 unsigned cntp_tval;
59 unsigned cntp_ctl;
60 unsigned long long cntv_cval;
61 unsigned cntv_tval;
62 unsigned cntv_ctl;
63 unsigned long long cnthp_cval;
64 unsigned cnthp_tval;
65 unsigned cnthp_ctl;
66 } generic_timer_context;
67
68
69 static banked_cp15_context saved_cp15_context;
70 static generic_timer_context saved_cp15_timer_ctx;
71
72 static void __save_processor_state(struct ns_banked_cp15_context *ctxt)
73 {
74 /* save preempt state and disable it */
75 preempt_disable();
76
77 // The 32-bit Generic timer context
78 save_generic_timer(&saved_cp15_timer_ctx, 0x0);
79
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);
84 }
85
86 void save_processor_state(void)
87 {
88 __save_processor_state(&saved_cp15_context);
89 }
90
91 static void __restore_processor_state(struct ns_banked_cp15_context *ctxt)
92 {
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);
97
98 // The 32-bit Generic timer context
99 restore_generic_timer(&saved_cp15_timer_ctx, 0x0);
100
101 // restore ETM module
102 #ifdef CONFIG_MTK_ETM
103 trace_stop_dormant();
104 trace_start_dormant();
105 #endif
106 /* restore preempt state */
107 preempt_enable();
108 }
109
110 void restore_processor_state(void)
111 {
112 __restore_processor_state(&saved_cp15_context);
113 }
114
115 EXPORT_SYMBOL(save_processor_state);
116 EXPORT_SYMBOL(restore_processor_state);
117 extern const void __nosave_begin, __nosave_end;
118
119 int pfn_is_nosave(unsigned long pfn)
120 {
121 unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
122 unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
123
124 return (pfn >= begin_pfn) && (pfn < end_pfn);
125 }