diff options
-rw-r--r-- | arch/arm64/include/asm/proc-fns.h | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/process.c | 30 | ||||
-rw-r--r-- | arch/arm64/mm/proc.S | 15 |
3 files changed, 19 insertions, 28 deletions
diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h index 0c657bb54597..9a8fd84f8fb2 100644 --- a/arch/arm64/include/asm/proc-fns.h +++ b/arch/arm64/include/asm/proc-fns.h | |||
@@ -32,6 +32,8 @@ extern void cpu_cache_off(void); | |||
32 | extern void cpu_do_idle(void); | 32 | extern void cpu_do_idle(void); |
33 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | 33 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); |
34 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); | 34 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); |
35 | void cpu_soft_restart(phys_addr_t cpu_reset, | ||
36 | unsigned long addr) __attribute__((noreturn)); | ||
35 | extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr); | 37 | extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr); |
36 | extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr); | 38 | extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr); |
37 | 39 | ||
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1309d64aa926..bf669228a59f 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c | |||
@@ -57,36 +57,10 @@ unsigned long __stack_chk_guard __read_mostly; | |||
57 | EXPORT_SYMBOL(__stack_chk_guard); | 57 | EXPORT_SYMBOL(__stack_chk_guard); |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | static void setup_restart(void) | ||
61 | { | ||
62 | /* | ||
63 | * Tell the mm system that we are going to reboot - | ||
64 | * we may need it to insert some 1:1 mappings so that | ||
65 | * soft boot works. | ||
66 | */ | ||
67 | setup_mm_for_reboot(); | ||
68 | |||
69 | /* Clean and invalidate caches */ | ||
70 | flush_cache_all(); | ||
71 | |||
72 | /* Turn D-cache off */ | ||
73 | cpu_cache_off(); | ||
74 | |||
75 | /* Push out any further dirty data, and ensure cache is empty */ | ||
76 | flush_cache_all(); | ||
77 | } | ||
78 | |||
79 | void soft_restart(unsigned long addr) | 60 | void soft_restart(unsigned long addr) |
80 | { | 61 | { |
81 | typedef void (*phys_reset_t)(unsigned long); | 62 | setup_mm_for_reboot(); |
82 | phys_reset_t phys_reset; | 63 | cpu_soft_restart(virt_to_phys(cpu_reset), addr); |
83 | |||
84 | setup_restart(); | ||
85 | |||
86 | /* Switch to the identity mapping */ | ||
87 | phys_reset = (phys_reset_t)virt_to_phys(cpu_reset); | ||
88 | phys_reset(addr); | ||
89 | |||
90 | /* Should never get here */ | 64 | /* Should never get here */ |
91 | BUG(); | 65 | BUG(); |
92 | } | 66 | } |
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 7736779c9809..4e778b13291b 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S | |||
@@ -76,6 +76,21 @@ ENTRY(cpu_reset) | |||
76 | ret x0 | 76 | ret x0 |
77 | ENDPROC(cpu_reset) | 77 | ENDPROC(cpu_reset) |
78 | 78 | ||
79 | ENTRY(cpu_soft_restart) | ||
80 | /* Save address of cpu_reset() and reset address */ | ||
81 | mov x19, x0 | ||
82 | mov x20, x1 | ||
83 | |||
84 | /* Turn D-cache off */ | ||
85 | bl cpu_cache_off | ||
86 | |||
87 | /* Push out all dirty data, and ensure cache is empty */ | ||
88 | bl flush_cache_all | ||
89 | |||
90 | mov x0, x20 | ||
91 | ret x19 | ||
92 | ENDPROC(cpu_soft_restart) | ||
93 | |||
79 | /* | 94 | /* |
80 | * cpu_do_idle() | 95 | * cpu_do_idle() |
81 | * | 96 | * |