aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/process.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-06 21:15:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-06 21:15:25 -0500
commit770e1b035dcb6ec3f8ee69dda0815dd1e220a683 (patch)
treee6d36abfdb053fbc722aea8d7e946d6d1b93c7e1 /arch/arm/kernel/process.c
parentd3d0b024348c040f0d6851e2e59fc961677d5169 (diff)
parent7b9dd47136c07ffd883aff6926c7b281e4c1eea4 (diff)
Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm
* 'for-linus' of git://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm: (207 commits) ARM: 7267/1: Remove BUILD_BUG_ON from asm/bug.h ARM: 7269/1: mach-sa1100: fix sched_clock breakage ARM: 7198/1: arm/imx6: add restart support for imx6q ARM: restart: remove the now empty arch_reset() ARM: restart: remove comments about adding code to arch_reset() ARM: restart: lpc32xx & u300: remove unnecessary printk ARM: restart: plat-samsung: remove plat/reset.h and s5p_reset_hook ARM: restart: w90x900: use new restart hook ARM: restart: Versatile Express: use new restart hook ARM: restart: versatile: use new restart hook ARM: restart: u300: use new restart hook ARM: restart: tegra: use new restart hook ARM: restart: spear: use new restart hook ARM: restart: shark: use new restart hook ARM: restart: sa1100: use new restart hook ARM: 7252/1: restart: S5PV210: use new restart hook ARM: 7251/1: restart: S5PC100: use new restart hook ARM: 7250/1: restart: S5P64X0: use new restart hook ARM: 7266/1: restart: S3C64XX: use new restart hook ARM: 7265/1: restart: S3C24XX: use new restart hook ... Fix up trivial conflict in arch/arm/mm/init.c due to removal of memblock_init() clashing with the movement of the sorting of the meminfo array.
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r--arch/arm/kernel/process.c77
1 files changed, 54 insertions, 23 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index e8e8fe505df1..971d65c253a9 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -57,7 +57,7 @@ static const char *isa_modes[] = {
57 "ARM" , "Thumb" , "Jazelle", "ThumbEE" 57 "ARM" , "Thumb" , "Jazelle", "ThumbEE"
58}; 58};
59 59
60extern void setup_mm_for_reboot(char mode); 60extern void setup_mm_for_reboot(void);
61 61
62static volatile int hlt_counter; 62static volatile int hlt_counter;
63 63
@@ -92,18 +92,24 @@ static int __init hlt_setup(char *__unused)
92__setup("nohlt", nohlt_setup); 92__setup("nohlt", nohlt_setup);
93__setup("hlt", hlt_setup); 93__setup("hlt", hlt_setup);
94 94
95void arm_machine_restart(char mode, const char *cmd) 95extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
96typedef void (*phys_reset_t)(unsigned long);
97
98/*
99 * A temporary stack to use for CPU reset. This is static so that we
100 * don't clobber it with the identity mapping. When running with this
101 * stack, any references to the current task *will not work* so you
102 * should really do as little as possible before jumping to your reset
103 * code.
104 */
105static u64 soft_restart_stack[16];
106
107static void __soft_restart(void *addr)
96{ 108{
97 /* Disable interrupts first */ 109 phys_reset_t phys_reset;
98 local_irq_disable();
99 local_fiq_disable();
100 110
101 /* 111 /* Take out a flat memory mapping. */
102 * Tell the mm system that we are going to reboot - 112 setup_mm_for_reboot();
103 * we may need it to insert some 1:1 mappings so that
104 * soft boot works.
105 */
106 setup_mm_for_reboot(mode);
107 113
108 /* Clean and invalidate caches */ 114 /* Clean and invalidate caches */
109 flush_cache_all(); 115 flush_cache_all();
@@ -114,18 +120,35 @@ void arm_machine_restart(char mode, const char *cmd)
114 /* Push out any further dirty data, and ensure cache is empty */ 120 /* Push out any further dirty data, and ensure cache is empty */
115 flush_cache_all(); 121 flush_cache_all();
116 122
117 /* 123 /* Switch to the identity mapping. */
118 * Now call the architecture specific reboot code. 124 phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
119 */ 125 phys_reset((unsigned long)addr);
120 arch_reset(mode, cmd);
121 126
122 /* 127 /* Should never get here. */
123 * Whoops - the architecture was unable to reboot. 128 BUG();
124 * Tell the user! 129}
125 */ 130
126 mdelay(1000); 131void soft_restart(unsigned long addr)
127 printk("Reboot failed -- System halted\n"); 132{
128 while (1); 133 u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
134
135 /* Disable interrupts first */
136 local_irq_disable();
137 local_fiq_disable();
138
139 /* Disable the L2 if we're the last man standing. */
140 if (num_online_cpus() == 1)
141 outer_disable();
142
143 /* Change to the new stack and continue with the reset. */
144 call_with_stack(__soft_restart, (void *)addr, (void *)stack);
145
146 /* Should never get here. */
147 BUG();
148}
149
150static void null_restart(char mode, const char *cmd)
151{
129} 152}
130 153
131/* 154/*
@@ -134,7 +157,7 @@ void arm_machine_restart(char mode, const char *cmd)
134void (*pm_power_off)(void); 157void (*pm_power_off)(void);
135EXPORT_SYMBOL(pm_power_off); 158EXPORT_SYMBOL(pm_power_off);
136 159
137void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; 160void (*arm_pm_restart)(char str, const char *cmd) = null_restart;
138EXPORT_SYMBOL_GPL(arm_pm_restart); 161EXPORT_SYMBOL_GPL(arm_pm_restart);
139 162
140static void do_nothing(void *unused) 163static void do_nothing(void *unused)
@@ -255,7 +278,15 @@ void machine_power_off(void)
255void machine_restart(char *cmd) 278void machine_restart(char *cmd)
256{ 279{
257 machine_shutdown(); 280 machine_shutdown();
281
258 arm_pm_restart(reboot_mode, cmd); 282 arm_pm_restart(reboot_mode, cmd);
283
284 /* Give a grace period for failure to restart of 1s */
285 mdelay(1000);
286
287 /* Whoops - the platform was unable to reboot. Tell the user! */
288 printk("Reboot failed -- System halted\n");
289 while (1);
259} 290}
260 291
261void __show_regs(struct pt_regs *regs) 292void __show_regs(struct pt_regs *regs)