aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r--arch/arm/kernel/process.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ba298277becd..30494aab829a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -86,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off);
86 */ 86 */
87void default_idle(void) 87void default_idle(void)
88{ 88{
89 local_irq_disable(); 89 if (hlt_counter)
90 if (!need_resched() && !hlt_counter) { 90 cpu_relax();
91 timer_dyn_reprogram(); 91 else {
92 arch_idle(); 92 local_irq_disable();
93 if (!need_resched()) {
94 timer_dyn_reprogram();
95 arch_idle();
96 }
97 local_irq_enable();
93 } 98 }
94 local_irq_enable();
95} 99}
96 100
97/* 101/*
@@ -116,13 +120,13 @@ void cpu_idle(void)
116 120
117 if (!idle) 121 if (!idle)
118 idle = default_idle; 122 idle = default_idle;
119 preempt_disable();
120 leds_event(led_idle_start); 123 leds_event(led_idle_start);
121 while (!need_resched()) 124 while (!need_resched())
122 idle(); 125 idle();
123 leds_event(led_idle_end); 126 leds_event(led_idle_end);
124 preempt_enable(); 127 preempt_enable_no_resched();
125 schedule(); 128 schedule();
129 preempt_disable();
126 } 130 }
127} 131}
128 132
@@ -355,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
355 struct thread_info *thread = p->thread_info; 359 struct thread_info *thread = p->thread_info;
356 struct pt_regs *childregs; 360 struct pt_regs *childregs;
357 361
358 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; 362 childregs = (void *)thread + THREAD_START_SP - sizeof(*regs);
359 *childregs = *regs; 363 *childregs = *regs;
360 childregs->ARM_r0 = 0; 364 childregs->ARM_r0 = 0;
361 childregs->ARM_sp = stack_start; 365 childregs->ARM_sp = stack_start;