diff options
Diffstat (limited to 'arch/mn10300/kernel/process.c')
-rw-r--r-- | arch/mn10300/kernel/process.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 243e33cd874b..b2e85ed73a54 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c | |||
@@ -57,6 +57,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
57 | void (*pm_power_off)(void); | 57 | void (*pm_power_off)(void); |
58 | EXPORT_SYMBOL(pm_power_off); | 58 | EXPORT_SYMBOL(pm_power_off); |
59 | 59 | ||
60 | #if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU) | ||
60 | /* | 61 | /* |
61 | * we use this if we don't have any better idle routine | 62 | * we use this if we don't have any better idle routine |
62 | */ | 63 | */ |
@@ -69,6 +70,35 @@ static void default_idle(void) | |||
69 | local_irq_enable(); | 70 | local_irq_enable(); |
70 | } | 71 | } |
71 | 72 | ||
73 | #else /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */ | ||
74 | /* | ||
75 | * On SMP it's slightly faster (but much more power-consuming!) | ||
76 | * to poll the ->work.need_resched flag instead of waiting for the | ||
77 | * cross-CPU IPI to arrive. Use this option with caution. | ||
78 | */ | ||
79 | static inline void poll_idle(void) | ||
80 | { | ||
81 | int oldval; | ||
82 | |||
83 | local_irq_enable(); | ||
84 | |||
85 | /* | ||
86 | * Deal with another CPU just having chosen a thread to | ||
87 | * run here: | ||
88 | */ | ||
89 | oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); | ||
90 | |||
91 | if (!oldval) { | ||
92 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
93 | while (!need_resched()) | ||
94 | cpu_relax(); | ||
95 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
96 | } else { | ||
97 | set_need_resched(); | ||
98 | } | ||
99 | } | ||
100 | #endif /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */ | ||
101 | |||
72 | /* | 102 | /* |
73 | * the idle thread | 103 | * the idle thread |
74 | * - there's no useful work to be done, so just try to conserve power and have | 104 | * - there's no useful work to be done, so just try to conserve power and have |
@@ -77,8 +107,6 @@ static void default_idle(void) | |||
77 | */ | 107 | */ |
78 | void cpu_idle(void) | 108 | void cpu_idle(void) |
79 | { | 109 | { |
80 | int cpu = smp_processor_id(); | ||
81 | |||
82 | /* endless idle loop with no priority at all */ | 110 | /* endless idle loop with no priority at all */ |
83 | for (;;) { | 111 | for (;;) { |
84 | while (!need_resched()) { | 112 | while (!need_resched()) { |
@@ -86,8 +114,13 @@ void cpu_idle(void) | |||
86 | 114 | ||
87 | smp_rmb(); | 115 | smp_rmb(); |
88 | idle = pm_idle; | 116 | idle = pm_idle; |
89 | if (!idle) | 117 | if (!idle) { |
118 | #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU) | ||
119 | idle = poll_idle; | ||
120 | #else /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */ | ||
90 | idle = default_idle; | 121 | idle = default_idle; |
122 | #endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */ | ||
123 | } | ||
91 | idle(); | 124 | idle(); |
92 | } | 125 | } |
93 | 126 | ||
@@ -233,7 +266,7 @@ int copy_thread(unsigned long clone_flags, | |||
233 | } | 266 | } |
234 | 267 | ||
235 | /* set up things up so the scheduler can start the new task */ | 268 | /* set up things up so the scheduler can start the new task */ |
236 | p->thread.__frame = c_kregs; | 269 | p->thread.frame = c_kregs; |
237 | p->thread.a3 = (unsigned long) c_kregs; | 270 | p->thread.a3 = (unsigned long) c_kregs; |
238 | p->thread.sp = c_ksp; | 271 | p->thread.sp = c_ksp; |
239 | p->thread.pc = (unsigned long) ret_from_fork; | 272 | p->thread.pc = (unsigned long) ret_from_fork; |