summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/powernv/idle.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-06-13 23:05:46 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2017-06-19 19:46:26 +1000
commit2525db04d1cc53e1951143d1829aa75a78cc7f76 (patch)
tree8819d4117525b024be704ddc34ee0b5a560a4aff /arch/powerpc/platforms/powernv/idle.c
parent2201f994a5742c03e660623c385fd6897dd1fa2f (diff)
powerpc/powernv: Simplify lazy IRQ handling in CPU offline
Rather than concern ourselves with any soft-mask logic in the CPU hotplug handler, just hard disable interrupts. This ensures there are no lazy-irqs pending, which means we can call directly to idle instruction in order to sleep. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv/idle.c')
-rw-r--r--arch/powerpc/platforms/powernv/idle.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index f875879ff1eb..f188d84d9c59 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -352,25 +352,31 @@ void power9_idle(void)
/*
* pnv_cpu_offline: A function that puts the CPU into the deepest
* available platform idle state on a CPU-Offline.
+ * interrupts hard disabled and no lazy irq pending.
*/
unsigned long pnv_cpu_offline(unsigned int cpu)
{
unsigned long srr1;
-
u32 idle_states = pnv_get_supported_cpuidle_states();
+ ppc64_runlatch_off();
+
if (cpu_has_feature(CPU_FTR_ARCH_300) && deepest_stop_found) {
- srr1 = __power9_idle_type(pnv_deepest_stop_psscr_val,
- pnv_deepest_stop_psscr_mask);
+ unsigned long psscr;
+
+ psscr = mfspr(SPRN_PSSCR);
+ psscr = (psscr & ~pnv_deepest_stop_psscr_mask) |
+ pnv_deepest_stop_psscr_val;
+ srr1 = power9_idle_stop(psscr);
+
} else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
- srr1 = __power7_idle_type(PNV_THREAD_WINKLE);
+ srr1 = power7_idle_insn(PNV_THREAD_WINKLE);
} else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
(idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
- srr1 = __power7_idle_type(PNV_THREAD_SLEEP);
+ srr1 = power7_idle_insn(PNV_THREAD_SLEEP);
} else if (idle_states & OPAL_PM_NAP_ENABLED) {
- srr1 = __power7_idle_type(PNV_THREAD_NAP);
+ srr1 = power7_idle_insn(PNV_THREAD_NAP);
} else {
- ppc64_runlatch_off();
/* This is the fallback method. We emulate snooze */
while (!generic_check_cpu_restart(cpu)) {
HMT_low();
@@ -378,9 +384,10 @@ unsigned long pnv_cpu_offline(unsigned int cpu)
}
srr1 = 0;
HMT_medium();
- ppc64_runlatch_on();
}
+ ppc64_runlatch_on();
+
return srr1;
}
#endif