aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/suspend.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/suspend.c')
-rw-r--r--arch/arm64/kernel/suspend.c48
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
12extern int __cpu_suspend(unsigned long); 12extern 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 */
23int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr, 22void 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 */
63int cpu_suspend(unsigned long arg) 60int 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 */
80int __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