aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/proc-fns.h2
-rw-r--r--arch/arm64/kernel/process.c30
-rw-r--r--arch/arm64/mm/proc.S15
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);
32extern void cpu_do_idle(void); 32extern void cpu_do_idle(void);
33extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); 33extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
34extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); 34extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
35void cpu_soft_restart(phys_addr_t cpu_reset,
36 unsigned long addr) __attribute__((noreturn));
35extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr); 37extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr);
36extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr); 38extern 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;
57EXPORT_SYMBOL(__stack_chk_guard); 57EXPORT_SYMBOL(__stack_chk_guard);
58#endif 58#endif
59 59
60static 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
79void soft_restart(unsigned long addr) 60void 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
77ENDPROC(cpu_reset) 77ENDPROC(cpu_reset)
78 78
79ENTRY(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
92ENDPROC(cpu_soft_restart)
93
79/* 94/*
80 * cpu_do_idle() 95 * cpu_do_idle()
81 * 96 *