2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-17 02:20:36 +04:00
/*
* Idle daemon for PowerPC . Idle daemon will handle any action
* that needs to be taken when the system becomes idle .
*
2006-03-27 08:03:03 +04:00
* Originally written by Cort Dougan ( cort @ cs . nmt . edu ) .
* Subsequent 32 - bit hacking by Tom Rini , Armin Kuster ,
* Paul Mackerras and others .
2005-04-17 02:20:36 +04:00
*
* iSeries supported added by Mike Corrigan < mikejc @ us . ibm . com >
*
* Additional shared processor , SMT , and firmware support
* Copyright ( c ) 2003 Dave Engebretsen < engebret @ us . ibm . com >
*
2006-03-27 08:03:03 +04:00
* 32 - bit and 64 - bit versions merged by Paul Mackerras < paulus @ samba . org >
2005-04-17 02:20:36 +04:00
*/
# include <linux/sched.h>
# include <linux/kernel.h>
# include <linux/smp.h>
# include <linux/cpu.h>
# include <linux/sysctl.h>
2007-09-21 07:26:03 +04:00
# include <linux/tick.h>
2005-04-17 02:20:36 +04:00
# include <asm/processor.h>
# include <asm/cputable.h>
# include <asm/time.h>
2005-07-08 04:56:28 +04:00
# include <asm/machdep.h>
2012-03-28 21:30:02 +04:00
# include <asm/runlatch.h>
2005-11-07 05:18:13 +03:00
# include <asm/smp.h>
2005-04-17 02:20:36 +04:00
2011-11-30 06:46:31 +04:00
unsigned long cpuidle_disable = IDLE_NO_OVERRIDE ;
EXPORT_SYMBOL ( cpuidle_disable ) ;
2006-10-24 20:31:26 +04:00
static int __init powersave_off ( char * arg )
{
ppc_md . power_save = NULL ;
2011-11-30 06:46:31 +04:00
cpuidle_disable = IDLE_POWERSAVE_OFF ;
2022-05-02 22:29:25 +03:00
return 1 ;
2006-10-24 20:31:26 +04:00
}
__setup ( " powersave=off " , powersave_off ) ;
2013-03-22 01:49:56 +04:00
void arch_cpu_idle ( void )
{
ppc64_runlatch_off ( ) ;
if ( ppc_md . power_save ) {
ppc_md . power_save ( ) ;
/*
* Some power_save functions return with
* interrupts enabled , some don ' t .
*/
2023-01-12 22:43:35 +03:00
if ( ! irqs_disabled ( ) )
raw_local_irq_disable ( ) ;
2013-03-22 01:49:56 +04:00
} else {
/*
* Go into low thread priority and possibly
* low power mode .
*/
HMT_low ( ) ;
HMT_very_low ( ) ;
2005-04-17 02:20:36 +04:00
}
2013-03-22 01:49:56 +04:00
HMT_medium ( ) ;
ppc64_runlatch_on ( ) ;
2005-04-17 02:20:36 +04:00
}
int powersave_nap ;
2019-07-11 05:24:03 +03:00
# ifdef CONFIG_PPC_970_NAP
void power4_idle ( void )
{
if ( ! cpu_has_feature ( CPU_FTR_CAN_NAP ) )
return ;
if ( ! powersave_nap )
return ;
if ( ! prep_irq_for_idle ( ) )
return ;
if ( cpu_has_feature ( CPU_FTR_ALTIVEC ) )
2021-12-21 08:59:03 +03:00
asm volatile ( PPC_DSSALL " ; sync " : : : " memory " ) ;
2019-07-11 05:24:03 +03:00
power4_idle_nap ( ) ;
/*
* power4_idle_nap returns with interrupts enabled ( soft and hard ) .
* to our caller with interrupts enabled ( soft and hard ) . Our caller
* can cope with either interrupts disabled or enabled upon return .
*/
}
# endif
2005-04-17 02:20:36 +04:00
# ifdef CONFIG_SYSCTL
/*
* Register the sysctl to set / clear powersave_nap .
*/
2013-06-14 06:37:30 +04:00
static struct ctl_table powersave_nap_ctl_table [ ] = {
2005-04-17 02:20:36 +04:00
{
. procname = " powersave-nap " ,
. data = & powersave_nap ,
. maxlen = sizeof ( int ) ,
. mode = 0644 ,
2009-11-16 14:11:48 +03:00
. proc_handler = proc_dointvec ,
2005-04-17 02:20:36 +04:00
} ,
} ;
static int __init
register_powersave_nap_sysctl ( void )
{
2023-03-11 02:28:49 +03:00
register_sysctl ( " kernel " , powersave_nap_ctl_table ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
__initcall ( register_powersave_nap_sysctl ) ;
# endif