Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7cd88da authored by Gautham R. Shenoy's avatar Gautham R. Shenoy Committed by Michael Ellerman
Browse files

powerpc/powernv: Move CPU-Offline idle state invocation from smp.c to idle.c



Move the piece of code in powernv/smp.c::pnv_smp_cpu_kill_self() which
transitions the CPU to the deepest available platform idle state to a
new function named pnv_cpu_offline() in powernv/idle.c. The rationale
behind this code movement is that the data required to determine the
deepest available platform state resides in powernv/idle.c.

Reviewed-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarGautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 2c9faa76
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ extern u32 pnv_fastsleep_workaround_at_exit[];

extern u64 pnv_first_deep_stop_state;

unsigned long pnv_cpu_offline(unsigned int cpu);
int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags);
static inline void report_invalid_psscr_val(u64 psscr_val, int err)
{
+25 −0
Original line number Diff line number Diff line
@@ -265,6 +265,31 @@ u64 pnv_first_deep_stop_state = MAX_STOP_STATE;
u64 pnv_deepest_stop_psscr_val;
u64 pnv_deepest_stop_psscr_mask;

/*
 * pnv_cpu_offline: A function that puts the CPU into the deepest
 * available platform idle state on a CPU-Offline.
 */
unsigned long pnv_cpu_offline(unsigned int cpu)
{
	unsigned long srr1;

	u32 idle_states = pnv_get_supported_cpuidle_states();

	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
		srr1 = power9_idle_stop(pnv_deepest_stop_psscr_val,
					pnv_deepest_stop_psscr_mask);
	} else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
		srr1 = power7_winkle();
	} else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
		   (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
		srr1 = power7_sleep();
	} else {
		srr1 = power7_nap(1);
	}

	return srr1;
}

/*
 * Power ISA 3.0 idle initialization.
 *
+0 −2
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ static inline void pnv_pci_shutdown(void) { }
#endif

extern u32 pnv_get_supported_cpuidle_states(void);
extern u64 pnv_deepest_stop_psscr_val;
extern u64 pnv_deepest_stop_psscr_mask;

extern void pnv_lpc_init(void);

+2 −16
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <asm/dbell.h>
#include <asm/kvm_ppc.h>
#include <asm/ppc-opcode.h>
#include <asm/cpuidle.h>

#include "powernv.h"

@@ -140,7 +141,6 @@ static void pnv_smp_cpu_kill_self(void)
{
	unsigned int cpu;
	unsigned long srr1, wmask;
	u32 idle_states;

	/* Standard hot unplug procedure */
	local_irq_disable();
@@ -155,8 +155,6 @@ static void pnv_smp_cpu_kill_self(void)
	if (cpu_has_feature(CPU_FTR_ARCH_207S))
		wmask = SRR1_WAKEMASK_P8;

	idle_states = pnv_get_supported_cpuidle_states();

	/* We don't want to take decrementer interrupts while we are offline,
	 * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9)
	 * enabled as to let IPIs in.
@@ -184,19 +182,7 @@ static void pnv_smp_cpu_kill_self(void)
		kvmppc_set_host_ipi(cpu, 0);

		ppc64_runlatch_off();

		if (cpu_has_feature(CPU_FTR_ARCH_300)) {
			srr1 = power9_idle_stop(pnv_deepest_stop_psscr_val,
						pnv_deepest_stop_psscr_mask);
		} else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
			srr1 = power7_winkle();
		} else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
			   (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
			srr1 = power7_sleep();
		} else {
			srr1 = power7_nap(1);
		}

		srr1 = pnv_cpu_offline(cpu);
		ppc64_runlatch_on();

		/*