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.c78
1 files changed, 29 insertions, 49 deletions
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index fe59ccfc115..be616ee0cf8 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -1,7 +1,7 @@
/*
* The idle loop for all SuperH platforms.
*
- * Copyright (C) 2002 - 2008 Paul Mundt
+ * Copyright (C) 2002 - 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -15,67 +15,47 @@
#include <linux/preempt.h>
#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);
-static 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;
+ /*
+ * If a platform has set its own idle routine, leave it alone.
+ */
+ if (!sh_idle)
+ sh_idle = default_idle;
+}
- tick_nohz_stop_sched_tick(1);
- while (!need_resched())
- idle();
- tick_nohz_restart_sched_tick();
+void stop_this_cpu(void *unused)
+{
+ local_irq_disable();
+ set_cpu_online(smp_processor_id(), false);
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- check_pgt_cache();
- }
+ for (;;)
+ cpu_sleep();
}