cpuidle/powernv: Add "Fast-Sleep" CPU idle state

Fast sleep is one of the deep idle states on Power8 in which local timers of
CPUs stop. On PowerPC we do not have an external clock device which can
handle wakeup of such CPUs. Now that we have the support in the tick broadcast
framework for archs that do not sport such a device and the low level support
for fast sleep, enable it in the cpuidle framework on PowerNV.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Preeti U Murthy
2014-02-26 05:39:06 +05:30
committed by Benjamin Herrenschmidt
父節點 97eb001f03
當前提交 0d94873011
共有 3 個文件被更改,包括 39 次插入1 次删除

查看文件

@@ -11,6 +11,7 @@
#include <linux/cpuidle.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <linux/clockchips.h>
#include <asm/machdep.h>
#include <asm/firmware.h>
@@ -49,6 +50,32 @@ static int nap_loop(struct cpuidle_device *dev,
return index;
}
static int fastsleep_loop(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
{
unsigned long old_lpcr = mfspr(SPRN_LPCR);
unsigned long new_lpcr;
if (unlikely(system_state < SYSTEM_RUNNING))
return index;
new_lpcr = old_lpcr;
new_lpcr &= ~(LPCR_MER | LPCR_PECE); /* lpcr[mer] must be 0 */
/* exit powersave upon external interrupt, but not decrementer
* interrupt.
*/
new_lpcr |= LPCR_PECE0;
mtspr(SPRN_LPCR, new_lpcr);
power7_sleep();
mtspr(SPRN_LPCR, old_lpcr);
return index;
}
/*
* States for dedicated partition case.
*/
@@ -67,6 +94,13 @@ static struct cpuidle_state powernv_states[] = {
.exit_latency = 10,
.target_residency = 100,
.enter = &nap_loop },
{ /* Fastsleep */
.name = "fastsleep",
.desc = "fastsleep",
.flags = CPUIDLE_FLAG_TIME_VALID,
.exit_latency = 10,
.target_residency = 100,
.enter = &fastsleep_loop },
};
static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n,