diff options
Diffstat (limited to 'arch/arm64/kernel/suspend.c')
-rw-r--r-- | arch/arm64/kernel/suspend.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 55a99b9a97e0..13ad4dbb1615 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c | |||
@@ -9,22 +9,19 @@ | |||
9 | #include <asm/suspend.h> | 9 | #include <asm/suspend.h> |
10 | #include <asm/tlbflush.h> | 10 | #include <asm/tlbflush.h> |
11 | 11 | ||
12 | extern int __cpu_suspend(unsigned long); | 12 | extern int __cpu_suspend_enter(unsigned long arg, int (*fn)(unsigned long)); |
13 | /* | 13 | /* |
14 | * This is called by __cpu_suspend() to save the state, and do whatever | 14 | * This is called by __cpu_suspend_enter() to save the state, and do whatever |
15 | * flushing is required to ensure that when the CPU goes to sleep we have | 15 | * flushing is required to ensure that when the CPU goes to sleep we have |
16 | * the necessary data available when the caches are not searched. | 16 | * the necessary data available when the caches are not searched. |
17 | * | 17 | * |
18 | * @arg: Argument to pass to suspend operations | 18 | * ptr: CPU context virtual address |
19 | * @ptr: CPU context virtual address | 19 | * save_ptr: address of the location where the context physical address |
20 | * @save_ptr: address of the location where the context physical address | 20 | * must be saved |
21 | * must be saved | ||
22 | */ | 21 | */ |
23 | int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr, | 22 | void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr, |
24 | phys_addr_t *save_ptr) | 23 | phys_addr_t *save_ptr) |
25 | { | 24 | { |
26 | int cpu = smp_processor_id(); | ||
27 | |||
28 | *save_ptr = virt_to_phys(ptr); | 25 | *save_ptr = virt_to_phys(ptr); |
29 | 26 | ||
30 | cpu_do_suspend(ptr); | 27 | cpu_do_suspend(ptr); |
@@ -35,8 +32,6 @@ int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr, | |||
35 | */ | 32 | */ |
36 | __flush_dcache_area(ptr, sizeof(*ptr)); | 33 | __flush_dcache_area(ptr, sizeof(*ptr)); |
37 | __flush_dcache_area(save_ptr, sizeof(*save_ptr)); | 34 | __flush_dcache_area(save_ptr, sizeof(*save_ptr)); |
38 | |||
39 | return cpu_ops[cpu]->cpu_suspend(arg); | ||
40 | } | 35 | } |
41 | 36 | ||
42 | /* | 37 | /* |
@@ -56,15 +51,15 @@ void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *)) | |||
56 | } | 51 | } |
57 | 52 | ||
58 | /** | 53 | /** |
59 | * cpu_suspend | 54 | * cpu_suspend() - function to enter a low-power state |
55 | * @arg: argument to pass to CPU suspend operations | ||
60 | * | 56 | * |
61 | * @arg: argument to pass to the finisher function | 57 | * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU |
58 | * operations back-end error code otherwise. | ||
62 | */ | 59 | */ |
63 | int cpu_suspend(unsigned long arg) | 60 | int cpu_suspend(unsigned long arg) |
64 | { | 61 | { |
65 | struct mm_struct *mm = current->active_mm; | 62 | int cpu = smp_processor_id(); |
66 | int ret, cpu = smp_processor_id(); | ||
67 | unsigned long flags; | ||
68 | 63 | ||
69 | /* | 64 | /* |
70 | * If cpu_ops have not been registered or suspend | 65 | * If cpu_ops have not been registered or suspend |
@@ -72,6 +67,21 @@ int cpu_suspend(unsigned long arg) | |||
72 | */ | 67 | */ |
73 | if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend) | 68 | if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend) |
74 | return -EOPNOTSUPP; | 69 | return -EOPNOTSUPP; |
70 | return cpu_ops[cpu]->cpu_suspend(arg); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * __cpu_suspend | ||
75 | * | ||
76 | * arg: argument to pass to the finisher function | ||
77 | * fn: finisher function pointer | ||
78 | * | ||
79 | */ | ||
80 | int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) | ||
81 | { | ||
82 | struct mm_struct *mm = current->active_mm; | ||
83 | int ret; | ||
84 | unsigned long flags; | ||
75 | 85 | ||
76 | /* | 86 | /* |
77 | * From this point debug exceptions are disabled to prevent | 87 | * From this point debug exceptions are disabled to prevent |
@@ -86,7 +96,7 @@ int cpu_suspend(unsigned long arg) | |||
86 | * page tables, so that the thread address space is properly | 96 | * page tables, so that the thread address space is properly |
87 | * set-up on function return. | 97 | * set-up on function return. |
88 | */ | 98 | */ |
89 | ret = __cpu_suspend(arg); | 99 | ret = __cpu_suspend_enter(arg, fn); |
90 | if (ret == 0) { | 100 | if (ret == 0) { |
91 | cpu_switch_mm(mm->pgd, mm); | 101 | cpu_switch_mm(mm->pgd, mm); |
92 | flush_tlb_all(); | 102 | flush_tlb_all(); |
@@ -95,7 +105,7 @@ int cpu_suspend(unsigned long arg) | |||
95 | * Restore per-cpu offset before any kernel | 105 | * Restore per-cpu offset before any kernel |
96 | * subsystem relying on it has a chance to run. | 106 | * subsystem relying on it has a chance to run. |
97 | */ | 107 | */ |
98 | set_my_cpu_offset(per_cpu_offset(cpu)); | 108 | set_my_cpu_offset(per_cpu_offset(smp_processor_id())); |
99 | 109 | ||
100 | /* | 110 | /* |
101 | * Restore HW breakpoint registers to sane values | 111 | * Restore HW breakpoint registers to sane values |