2008-11-26 15:52:44 +09:00
/*
* The idle loop for all SuperH platforms .
*
* Copyright ( C ) 2002 - 2008 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
* for more details .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/mm.h>
# include <linux/pm.h>
# include <linux/tick.h>
# include <linux/preempt.h>
# include <linux/thread_info.h>
# include <linux/irqflags.h>
# include <asm/pgalloc.h>
# include <asm/system.h>
# include <asm/atomic.h>
static int hlt_counter ;
void ( * pm_idle ) ( void ) ;
void ( * pm_power_off ) ( void ) ;
EXPORT_SYMBOL ( pm_power_off ) ;
static int __init nohlt_setup ( char * __unused )
{
hlt_counter = 1 ;
return 1 ;
}
__setup ( " nohlt " , nohlt_setup ) ;
static int __init hlt_setup ( char * __unused )
{
hlt_counter = 0 ;
return 1 ;
}
__setup ( " hlt " , hlt_setup ) ;
2009-04-02 13:08:31 +09:00
void default_idle ( void )
2008-11-26 15:52:44 +09:00
{
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 ( ) ;
}
void cpu_idle ( 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 ( ) ;
}
}