1 /* 2 * The idle loop for all SuperH platforms. 3 * 4 * Copyright (C) 2002 - 2008 Paul Mundt 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 #include <linux/module.h> 11 #include <linux/init.h> 12 #include <linux/mm.h> 13 #include <linux/pm.h> 14 #include <linux/tick.h> 15 #include <linux/preempt.h> 16 #include <linux/thread_info.h> 17 #include <linux/irqflags.h> 18 #include <asm/pgalloc.h> 19 #include <asm/system.h> 20 #include <asm/atomic.h> 21 22 static int hlt_counter; 23 void (*pm_idle)(void); 24 void (*pm_power_off)(void); 25 EXPORT_SYMBOL(pm_power_off); 26 27 static int __init nohlt_setup(char *__unused) 28 { 29 hlt_counter = 1; 30 return 1; 31 } 32 __setup("nohlt", nohlt_setup); 33 34 static int __init hlt_setup(char *__unused) 35 { 36 hlt_counter = 0; 37 return 1; 38 } 39 __setup("hlt", hlt_setup); 40 41 void default_idle(void) 42 { 43 if (!hlt_counter) { 44 clear_thread_flag(TIF_POLLING_NRFLAG); 45 smp_mb__after_clear_bit(); 46 set_bl_bit(); 47 stop_critical_timings(); 48 49 while (!need_resched()) 50 cpu_sleep(); 51 52 start_critical_timings(); 53 clear_bl_bit(); 54 set_thread_flag(TIF_POLLING_NRFLAG); 55 } else 56 while (!need_resched()) 57 cpu_relax(); 58 } 59 60 void cpu_idle(void) 61 { 62 set_thread_flag(TIF_POLLING_NRFLAG); 63 64 /* endless idle loop with no priority at all */ 65 while (1) { 66 void (*idle)(void) = pm_idle; 67 68 if (!idle) 69 idle = default_idle; 70 71 tick_nohz_stop_sched_tick(1); 72 while (!need_resched()) 73 idle(); 74 tick_nohz_restart_sched_tick(); 75 76 preempt_enable_no_resched(); 77 schedule(); 78 preempt_disable(); 79 check_pgt_cache(); 80 } 81 } 82