aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/kernel/process.c')
-rw-r--r--arch/mn10300/kernel/process.c41
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)
57void (*pm_power_off)(void); 57void (*pm_power_off)(void);
58EXPORT_SYMBOL(pm_power_off); 58EXPORT_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 */
79static 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 */
78void cpu_idle(void) 108void 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;