diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r-- | arch/mips/kernel/process.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 1eaaa450e20c..f3d73e1831c1 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -50,10 +50,15 @@ | |||
50 | */ | 50 | */ |
51 | void __noreturn cpu_idle(void) | 51 | void __noreturn cpu_idle(void) |
52 | { | 52 | { |
53 | int cpu; | ||
54 | |||
55 | /* CPU is going idle. */ | ||
56 | cpu = smp_processor_id(); | ||
57 | |||
53 | /* endless idle loop with no priority at all */ | 58 | /* endless idle loop with no priority at all */ |
54 | while (1) { | 59 | while (1) { |
55 | tick_nohz_stop_sched_tick(1); | 60 | tick_nohz_stop_sched_tick(1); |
56 | while (!need_resched()) { | 61 | while (!need_resched() && cpu_online(cpu)) { |
57 | #ifdef CONFIG_MIPS_MT_SMTC | 62 | #ifdef CONFIG_MIPS_MT_SMTC |
58 | extern void smtc_idle_loop_hook(void); | 63 | extern void smtc_idle_loop_hook(void); |
59 | 64 | ||
@@ -62,6 +67,12 @@ void __noreturn cpu_idle(void) | |||
62 | if (cpu_wait) | 67 | if (cpu_wait) |
63 | (*cpu_wait)(); | 68 | (*cpu_wait)(); |
64 | } | 69 | } |
70 | #ifdef CONFIG_HOTPLUG_CPU | ||
71 | if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && | ||
72 | (system_state == SYSTEM_RUNNING || | ||
73 | system_state == SYSTEM_BOOTING)) | ||
74 | play_dead(); | ||
75 | #endif | ||
65 | tick_nohz_restart_sched_tick(); | 76 | tick_nohz_restart_sched_tick(); |
66 | preempt_enable_no_resched(); | 77 | preempt_enable_no_resched(); |
67 | schedule(); | 78 | schedule(); |
@@ -104,7 +115,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
104 | { | 115 | { |
105 | struct thread_info *ti = task_thread_info(p); | 116 | struct thread_info *ti = task_thread_info(p); |
106 | struct pt_regs *childregs; | 117 | struct pt_regs *childregs; |
107 | long childksp; | 118 | unsigned long childksp; |
108 | p->set_child_tid = p->clear_child_tid = NULL; | 119 | p->set_child_tid = p->clear_child_tid = NULL; |
109 | 120 | ||
110 | childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; | 121 | childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; |
@@ -121,6 +132,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
121 | 132 | ||
122 | /* set up new TSS. */ | 133 | /* set up new TSS. */ |
123 | childregs = (struct pt_regs *) childksp - 1; | 134 | childregs = (struct pt_regs *) childksp - 1; |
135 | /* Put the stack after the struct pt_regs. */ | ||
136 | childksp = (unsigned long) childregs; | ||
124 | *childregs = *regs; | 137 | *childregs = *regs; |
125 | childregs->regs[7] = 0; /* Clear error flag */ | 138 | childregs->regs[7] = 0; /* Clear error flag */ |
126 | 139 | ||