diff options
Diffstat (limited to 'arch/powerpc/kernel/idle.c')
| -rw-r--r-- | arch/powerpc/kernel/idle.c | 34 | 
1 files changed, 32 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 39a2baa6ad58..0a48bf5db6c8 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -39,9 +39,13 @@  #define cpu_should_die()	0  #endif +unsigned long cpuidle_disable = IDLE_NO_OVERRIDE; +EXPORT_SYMBOL(cpuidle_disable); +  static int __init powersave_off(char *arg)  {  	ppc_md.power_save = NULL; +	cpuidle_disable = IDLE_POWERSAVE_OFF;  	return 0;  }  __setup("powersave=off", powersave_off); @@ -56,7 +60,9 @@ void cpu_idle(void)  	set_thread_flag(TIF_POLLING_NRFLAG);  	while (1) { -		tick_nohz_stop_sched_tick(1); +		tick_nohz_idle_enter(); +		rcu_idle_enter(); +  		while (!need_resched() && !cpu_should_die()) {  			ppc64_runlatch_off(); @@ -93,7 +99,8 @@ void cpu_idle(void)  		HMT_medium();  		ppc64_runlatch_on(); -		tick_nohz_restart_sched_tick(); +		rcu_idle_exit(); +		tick_nohz_idle_exit();  		preempt_enable_no_resched();  		if (cpu_should_die())  			cpu_die(); @@ -102,6 +109,29 @@ void cpu_idle(void)  	}  } + +/* + * cpu_idle_wait - Used to ensure that all the CPUs come out of the old + * idle loop and start using the new idle loop. + * Required while changing idle handler on SMP systems. + * Caller must have changed idle handler to the new value before the call. + * This window may be larger on shared systems. + */ +void cpu_idle_wait(void) +{ +	int cpu; +	smp_mb(); + +	/* kick all the CPUs so that they exit out of old idle routine */ +	get_online_cpus(); +	for_each_online_cpu(cpu) { +		if (cpu != smp_processor_id()) +			smp_send_reschedule(cpu); +	} +	put_online_cpus(); +} +EXPORT_SYMBOL_GPL(cpu_idle_wait); +  int powersave_nap;  #ifdef CONFIG_SYSCTL  |