aboutsummaryrefslogtreecommitdiff
path: root/arch/sh/kernel/idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/idle.c')
-rw-r--r--arch/sh/kernel/idle.c91
1 files changed, 25 insertions, 66 deletions
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 27ff2dc093c..be616ee0cf8 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -16,87 +16,46 @@
#include <linux/thread_info.h>
#include <linux/irqflags.h>
#include <linux/smp.h>
+#include <linux/atomic.h>
#include <asm/pgalloc.h>
-#include <asm/system.h>
-#include <asm/atomic.h>
+#include <asm/smp.h>
+#include <asm/bl_bit.h>
-static int hlt_counter;
-void (*pm_idle)(void);
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
+static void (*sh_idle)(void);
-static int __init nohlt_setup(char *__unused)
+void default_idle(void)
{
- hlt_counter = 1;
- return 1;
+ set_bl_bit();
+ local_irq_enable();
+ /* Isn't this racy ? */
+ cpu_sleep();
+ clear_bl_bit();
}
-__setup("nohlt", nohlt_setup);
-static int __init hlt_setup(char *__unused)
+void arch_cpu_idle_dead(void)
{
- hlt_counter = 0;
- return 1;
+ play_dead();
}
-__setup("hlt", hlt_setup);
-void default_idle(void)
+void arch_cpu_idle(void)
{
- if (!hlt_counter) {
- clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb__after_clear_bit();
- set_bl_bit();
- stop_critical_timings();
-
- while (!need_resched())
- cpu_sleep();
-
- start_critical_timings();
- clear_bl_bit();
- set_thread_flag(TIF_POLLING_NRFLAG);
- } else
- while (!need_resched())
- cpu_relax();
+ sh_idle();
}
-void cpu_idle(void)
+void __init select_idle_routine(void)
{
- set_thread_flag(TIF_POLLING_NRFLAG);
-
- /* endless idle loop with no priority at all */
- while (1) {
- void (*idle)(void) = pm_idle;
-
- if (!idle)
- idle = default_idle;
-
- tick_nohz_stop_sched_tick(1);
- while (!need_resched())
- idle();
- tick_nohz_restart_sched_tick();
-
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- check_pgt_cache();
- }
+ /*
+ * If a platform has set its own idle routine, leave it alone.
+ */
+ if (!sh_idle)
+ sh_idle = default_idle;
}
-static void do_nothing(void *unused)
+void stop_this_cpu(void *unused)
{
-}
+ local_irq_disable();
+ set_cpu_online(smp_processor_id(), false);
-/*
- * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
- * pm_idle and update to new pm_idle value. Required while changing pm_idle
- * handler on SMP systems.
- *
- * Caller must have changed pm_idle to the new value before the call. Old
- * pm_idle value will not be used by any CPU after the return of this function.
- */
-void cpu_idle_wait(void)
-{
- smp_mb();
- /* kick all the CPUs so that they exit out of pm_idle */
- smp_call_function(do_nothing, NULL, 1);
+ for (;;)
+ cpu_sleep();
}
-EXPORT_SYMBOL_GPL(cpu_idle_wait);