// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PowerNV cpuidle code
 *
 * Copyright 2015 IBM Corp.
 */

#include <linux/types.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/device.h>
#include <linux/cpu.h>

#include <asm/asm-prototypes.h>
#include <asm/firmware.h>
#include <asm/machdep.h>
#include <asm/opal.h>
#include <asm/cputhreads.h>
#include <asm/cpuidle.h>
#include <asm/code-patching.h>
#include <asm/smp.h>
#include <asm/runlatch.h>
#include <asm/dbell.h>

#include "powernv.h"
#include "subcore.h"

/* Power ISA 3.0 allows for stop states 0x0 - 0xF */
#define MAX_STOP_STATE	0xF

#define P9_STOP_SPR_MSR 2000
#define P9_STOP_SPR_PSSCR      855

static u32 supported_cpuidle_states;
struct pnv_idle_states_t *pnv_idle_states;
int nr_pnv_idle_states;

/*
 * The default stop state that will be used by ppc_md.power_save
 * function on platforms that support stop instruction.
 */
static u64 pnv_default_stop_val;
static u64 pnv_default_stop_mask;
static bool default_stop_found;

/*
 * First stop state levels when SPR and TB loss can occur.
 */
static u64 pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
static u64 pnv_first_spr_loss_level = MAX_STOP_STATE + 1;

/*
 * psscr value and mask of the deepest stop idle state.
 * Used when a cpu is offlined.
 */
static u64 pnv_deepest_stop_psscr_val;
static u64 pnv_deepest_stop_psscr_mask;
static u64 pnv_deepest_stop_flag;
static bool deepest_stop_found;

static unsigned long power7_offline_type;

static int pnv_save_sprs_for_deep_states(void)
{
	int cpu;
	int rc;

	/*
	 * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across
	 * all cpus at boot. Get these reg values of current cpu and use the
	 * same across all cpus.
	 */
	uint64_t lpcr_val	= mfspr(SPRN_LPCR);
	uint64_t hid0_val	= mfspr(SPRN_HID0);
	uint64_t hid1_val	= mfspr(SPRN_HID1);
	uint64_t hid4_val	= mfspr(SPRN_HID4);
	uint64_t hid5_val	= mfspr(SPRN_HID5);
	uint64_t hmeer_val	= mfspr(SPRN_HMEER);
	uint64_t msr_val = MSR_IDLE;
	uint64_t psscr_val = pnv_deepest_stop_psscr_val;

	for_each_present_cpu(cpu) {
		uint64_t pir = get_hard_smp_processor_id(cpu);
		uint64_t hsprg0_val = (uint64_t)paca_ptrs[cpu];

		rc = opal_slw_set_reg(pir, SPRN_HSPRG0, hsprg0_val);
		if (rc != 0)
			return rc;

		rc = opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val);
		if (rc != 0)
			return rc;

		if (cpu_has_feature(CPU_FTR_ARCH_300)) {
			rc = opal_slw_set_reg(pir, P9_STOP_SPR_MSR, msr_val);
			if (rc)
				return rc;

			rc = opal_slw_set_reg(pir,
					      P9_STOP_SPR_PSSCR, psscr_val);

			if (rc)
				return rc;
		}

		/* HIDs are per core registers */
		if (cpu_thread_in_core(cpu) == 0) {

			rc = opal_slw_set_reg(pir, SPRN_HMEER, hmeer_val);
			if (rc != 0)
				return rc;

			rc = opal_slw_set_reg(pir, SPRN_HID0, hid0_val);
			if (rc != 0)
				return rc;

			/* Only p8 needs to set extra HID regiters */
			if (!cpu_has_feature(CPU_FTR_ARCH_300)) {

				rc = opal_slw_set_reg(pir, SPRN_HID1, hid1_val);
				if (rc != 0)
					return rc;

				rc = opal_slw_set_reg(pir, SPRN_HID4, hid4_val);
				if (rc != 0)
					return rc;

				rc = opal_slw_set_reg(pir, SPRN_HID5, hid5_val);
				if (rc != 0)
					return rc;
			}
		}
	}

	return 0;
}

u32 pnv_get_supported_cpuidle_states(void)
{
	return supported_cpuidle_states;
}
EXPORT_SYMBOL_GPL(pnv_get_supported_cpuidle_states);

static void pnv_fastsleep_workaround_apply(void *info)

{
	int rc;
	int *err = info;

	rc = opal_config_cpu_idle_state(OPAL_CONFIG_IDLE_FASTSLEEP,
					OPAL_CONFIG_IDLE_APPLY);
	if (rc)
		*err = 1;
}

static bool power7_fastsleep_workaround_entry = true;
static bool power7_fastsleep_workaround_exit = true;

/*
 * Used to store fastsleep workaround state
 * 0 - Workaround applied/undone at fastsleep entry/exit path (Default)
 * 1 - Workaround applied once, never undone.
 */
static u8 fastsleep_workaround_applyonce;

static ssize_t show_fastsleep_workaround_applyonce(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%u\n", fastsleep_workaround_applyonce);
}

static ssize_t store_fastsleep_workaround_applyonce(struct device *dev,
		struct device_attribute *attr, const char *buf,
		size_t count)
{
	cpumask_t primary_thread_mask;
	int err;
	u8 val;

	if (kstrtou8(buf, 0, &val) || val != 1)
		return -EINVAL;

	if (fastsleep_workaround_applyonce == 1)
		return count;

	/*
	 * fastsleep_workaround_applyonce = 1 implies
	 * fastsleep workaround needs to be left in 'applied' state on all
	 * the cores. Do this by-
	 * 1. Disable the 'undo' workaround in fastsleep exit path
	 * 2. Sendi IPIs to all the cores which have at least one online thread
	 * 3. Disable the 'apply' workaround in fastsleep entry path
	 *
	 * There is no need to send ipi to cores which have all threads
	 * offlined, as last thread of the core entering fastsleep or deeper
	 * state would have applied workaround.
	 */
	power7_fastsleep_workaround_exit = false;

	get_online_cpus();
	primary_thread_mask = cpu_online_cores_map();
	on_each_cpu_mask(&primary_thread_mask,
				pnv_fastsleep_workaround_apply,
				&err, 1);
	put_online_cpus();
	if (err) {
		pr_err("fastsleep_workaround_applyonce change failed while running pnv_fastsleep_workaround_apply");
		goto fail;
	}

	power7_fastsleep_workaround_entry = false;

	fastsleep_workaround_applyonce = 1;

	return count;
fail:
	return -EIO;
}

static DEVICE_ATTR(fastsleep_workaround_applyonce, 0600,
			show_fastsleep_workaround_applyonce,
			store_fastsleep_workaround_applyonce);

static inline void atomic_start_thread_idle(void)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	int thread_nr = cpu_thread_in_core(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;

	clear_bit(thread_nr, state);
}

static inline void atomic_stop_thread_idle(void)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	int thread_nr = cpu_thread_in_core(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;

	set_bit(thread_nr, state);
}

static inline void atomic_lock_thread_idle(void)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;

	while (unlikely(test_and_set_bit_lock(NR_PNV_CORE_IDLE_LOCK_BIT, state)))
		barrier();
}

static inline void atomic_unlock_and_stop_thread_idle(void)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	unsigned long thread = 1UL << cpu_thread_in_core(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;
	u64 s = READ_ONCE(*state);
	u64 new, tmp;

	BUG_ON(!(s & PNV_CORE_IDLE_LOCK_BIT));
	BUG_ON(s & thread);

again:
	new = (s | thread) & ~PNV_CORE_IDLE_LOCK_BIT;
	tmp = cmpxchg(state, s, new);
	if (unlikely(tmp != s)) {
		s = tmp;
		goto again;
	}
}

static inline void atomic_unlock_thread_idle(void)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;

	BUG_ON(!test_bit(NR_PNV_CORE_IDLE_LOCK_BIT, state));
	clear_bit_unlock(NR_PNV_CORE_IDLE_LOCK_BIT, state);
}

/* P7 and P8 */
struct p7_sprs {
	/* per core */
	u64 tscr;
	u64 worc;

	/* per subcore */
	u64 sdr1;
	u64 rpr;

	/* per thread */
	u64 lpcr;
	u64 hfscr;
	u64 fscr;
	u64 purr;
	u64 spurr;
	u64 dscr;
	u64 wort;

	/* per thread SPRs that get lost in shallow states */
	u64 amr;
	u64 iamr;
	u64 amor;
	u64 uamor;
};

static unsigned long power7_idle_insn(unsigned long type)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;
	unsigned long thread = 1UL << cpu_thread_in_core(cpu);
	unsigned long core_thread_mask = (1UL << threads_per_core) - 1;
	unsigned long srr1;
	bool full_winkle;
	struct p7_sprs sprs = {}; /* avoid false use-uninitialised */
	bool sprs_saved = false;
	int rc;

	if (unlikely(type != PNV_THREAD_NAP)) {
		atomic_lock_thread_idle();

		BUG_ON(!(*state & thread));
		*state &= ~thread;

		if (power7_fastsleep_workaround_entry) {
			if ((*state & core_thread_mask) == 0) {
				rc = opal_config_cpu_idle_state(
						OPAL_CONFIG_IDLE_FASTSLEEP,
						OPAL_CONFIG_IDLE_APPLY);
				BUG_ON(rc);
			}
		}

		if (type == PNV_THREAD_WINKLE) {
			sprs.tscr	= mfspr(SPRN_TSCR);
			sprs.worc	= mfspr(SPRN_WORC);

			sprs.sdr1	= mfspr(SPRN_SDR1);
			sprs.rpr	= mfspr(SPRN_RPR);

			sprs.lpcr	= mfspr(SPRN_LPCR);
			if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
				sprs.hfscr	= mfspr(SPRN_HFSCR);
				sprs.fscr	= mfspr(SPRN_FSCR);
			}
			sprs.purr	= mfspr(SPRN_PURR);
			sprs.spurr	= mfspr(SPRN_SPURR);
			sprs.dscr	= mfspr(SPRN_DSCR);
			sprs.wort	= mfspr(SPRN_WORT);

			sprs_saved = true;

			/*
			 * Increment winkle counter and set all winkle bits if
			 * all threads are winkling. This allows wakeup side to
			 * distinguish between fast sleep and winkle state
			 * loss. Fast sleep still has to resync the timebase so
			 * this may not be a really big win.
			 */
			*state += 1 << PNV_CORE_IDLE_WINKLE_COUNT_SHIFT;
			if ((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS)
					>> PNV_CORE_IDLE_WINKLE_COUNT_SHIFT
					== threads_per_core)
				*state |= PNV_CORE_IDLE_THREAD_WINKLE_BITS;
			WARN_ON((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS) == 0);
		}

		atomic_unlock_thread_idle();
	}

	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
		sprs.amr	= mfspr(SPRN_AMR);
		sprs.iamr	= mfspr(SPRN_IAMR);
		sprs.amor	= mfspr(SPRN_AMOR);
		sprs.uamor	= mfspr(SPRN_UAMOR);
	}

	local_paca->thread_idle_state = type;
	srr1 = isa206_idle_insn_mayloss(type);		/* go idle */
	local_paca->thread_idle_state = PNV_THREAD_RUNNING;

	WARN_ON_ONCE(!srr1);
	WARN_ON_ONCE(mfmsr() & (MSR_IR|MSR_DR));

	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
		if ((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS) {
			/*
			 * We don't need an isync after the mtsprs here because
			 * the upcoming mtmsrd is execution synchronizing.
			 */
			mtspr(SPRN_AMR,		sprs.amr);
			mtspr(SPRN_IAMR,	sprs.iamr);
			mtspr(SPRN_AMOR,	sprs.amor);
			mtspr(SPRN_UAMOR,	sprs.uamor);
		}
	}

	if (unlikely((srr1 & SRR1_WAKEMASK_P8) == SRR1_WAKEHMI))
		hmi_exception_realmode(NULL);

	if (likely((srr1 & SRR1_WAKESTATE) != SRR1_WS_HVLOSS)) {
		if (unlikely(type != PNV_THREAD_NAP)) {
			atomic_lock_thread_idle();
			if (type == PNV_THREAD_WINKLE) {
				WARN_ON((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS) == 0);
				*state -= 1 << PNV_CORE_IDLE_WINKLE_COUNT_SHIFT;
				*state &= ~(thread << PNV_CORE_IDLE_THREAD_WINKLE_BITS_SHIFT);
			}
			atomic_unlock_and_stop_thread_idle();
		}
		return srr1;
	}

	/* HV state loss */
	BUG_ON(type == PNV_THREAD_NAP);

	atomic_lock_thread_idle();

	full_winkle = false;
	if (type == PNV_THREAD_WINKLE) {
		WARN_ON((*state & PNV_CORE_IDLE_WINKLE_COUNT_BITS) == 0);
		*state -= 1 << PNV_CORE_IDLE_WINKLE_COUNT_SHIFT;
		if (*state & (thread << PNV_CORE_IDLE_THREAD_WINKLE_BITS_SHIFT)) {
			*state &= ~(thread << PNV_CORE_IDLE_THREAD_WINKLE_BITS_SHIFT);
			full_winkle = true;
			BUG_ON(!sprs_saved);
		}
	}

	WARN_ON(*state & thread);

	if ((*state & core_thread_mask) != 0)
		goto core_woken;

	/* Per-core SPRs */
	if (full_winkle) {
		mtspr(SPRN_TSCR,	sprs.tscr);
		mtspr(SPRN_WORC,	sprs.worc);
	}

	if (power7_fastsleep_workaround_exit) {
		rc = opal_config_cpu_idle_state(OPAL_CONFIG_IDLE_FASTSLEEP,
						OPAL_CONFIG_IDLE_UNDO);
		BUG_ON(rc);
	}

	/* TB */
	if (opal_resync_timebase() != OPAL_SUCCESS)
		BUG();

core_woken:
	if (!full_winkle)
		goto subcore_woken;

	if ((*state & local_paca->subcore_sibling_mask) != 0)
		goto subcore_woken;

	/* Per-subcore SPRs */
	mtspr(SPRN_SDR1,	sprs.sdr1);
	mtspr(SPRN_RPR,		sprs.rpr);

subcore_woken:
	/*
	 * isync after restoring shared SPRs and before unlocking. Unlock
	 * only contains hwsync which does not necessarily do the right
	 * thing for SPRs.
	 */
	isync();
	atomic_unlock_and_stop_thread_idle();

	/* Fast sleep does not lose SPRs */
	if (!full_winkle)
		return srr1;

	/* Per-thread SPRs */
	mtspr(SPRN_LPCR,	sprs.lpcr);
	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
		mtspr(SPRN_HFSCR,	sprs.hfscr);
		mtspr(SPRN_FSCR,	sprs.fscr);
	}
	mtspr(SPRN_PURR,	sprs.purr);
	mtspr(SPRN_SPURR,	sprs.spurr);
	mtspr(SPRN_DSCR,	sprs.dscr);
	mtspr(SPRN_WORT,	sprs.wort);

	mtspr(SPRN_SPRG3,	local_paca->sprg_vdso);

	/*
	 * The SLB has to be restored here, but it sometimes still
	 * contains entries, so the __ variant must be used to prevent
	 * multi hits.
	 */
	__slb_restore_bolted_realmode();

	return srr1;
}

extern unsigned long idle_kvm_start_guest(unsigned long srr1);

#ifdef CONFIG_HOTPLUG_CPU
static unsigned long power7_offline(void)
{
	unsigned long srr1;

	mtmsr(MSR_IDLE);

#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	/* Tell KVM we're entering idle. */
	/******************************************************/
	/*  N O T E   W E L L    ! ! !    N O T E   W E L L   */
	/* The following store to HSTATE_HWTHREAD_STATE(r13)  */
	/* MUST occur in real mode, i.e. with the MMU off,    */
	/* and the MMU must stay off until we clear this flag */
	/* and test HSTATE_HWTHREAD_REQ(r13) in               */
	/* pnv_powersave_wakeup in this file.                 */
	/* The reason is that another thread can switch the   */
	/* MMU to a guest context whenever this flag is set   */
	/* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on,    */
	/* that would potentially cause this thread to start  */
	/* executing instructions from guest memory in        */
	/* hypervisor mode, leading to a host crash or data   */
	/* corruption, or worse.                              */
	/******************************************************/
	local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_IDLE;
#endif

	__ppc64_runlatch_off();
	srr1 = power7_idle_insn(power7_offline_type);
	__ppc64_runlatch_on();

#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_KERNEL;
	/* Order setting hwthread_state vs. testing hwthread_req */
	smp_mb();
	if (local_paca->kvm_hstate.hwthread_req)
		srr1 = idle_kvm_start_guest(srr1);
#endif

	mtmsr(MSR_KERNEL);

	return srr1;
}
#endif

void power7_idle_type(unsigned long type)
{
	unsigned long srr1;

	if (!prep_irq_for_idle_irqsoff())
		return;

	mtmsr(MSR_IDLE);
	__ppc64_runlatch_off();
	srr1 = power7_idle_insn(type);
	__ppc64_runlatch_on();
	mtmsr(MSR_KERNEL);

	fini_irq_for_idle_irqsoff();
	irq_set_pending_from_srr1(srr1);
}

void power7_idle(void)
{
	if (!powersave_nap)
		return;

	power7_idle_type(PNV_THREAD_NAP);
}

struct p9_sprs {
	/* per core */
	u64 ptcr;
	u64 rpr;
	u64 tscr;
	u64 ldbar;

	/* per thread */
	u64 lpcr;
	u64 hfscr;
	u64 fscr;
	u64 pid;
	u64 purr;
	u64 spurr;
	u64 dscr;
	u64 wort;

	u64 mmcra;
	u32 mmcr0;
	u32 mmcr1;
	u64 mmcr2;

	/* per thread SPRs that get lost in shallow states */
	u64 amr;
	u64 iamr;
	u64 amor;
	u64 uamor;
};

static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
{
	int cpu = raw_smp_processor_id();
	int first = cpu_first_thread_sibling(cpu);
	unsigned long *state = &paca_ptrs[first]->idle_state;
	unsigned long core_thread_mask = (1UL << threads_per_core) - 1;
	unsigned long srr1;
	unsigned long pls;
	unsigned long mmcr0 = 0;
	struct p9_sprs sprs = {}; /* avoid false used-uninitialised */
	bool sprs_saved = false;

	if (!(psscr & (PSSCR_EC|PSSCR_ESL))) {
		/* EC=ESL=0 case */

		BUG_ON(!mmu_on);

		/*
		 * Wake synchronously. SRESET via xscom may still cause
		 * a 0x100 powersave wakeup with SRR1 reason!
		 */
		srr1 = isa300_idle_stop_noloss(psscr);		/* go idle */
		if (likely(!srr1))
			return 0;

		/*
		 * Registers not saved, can't recover!
		 * This would be a hardware bug
		 */
		BUG_ON((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS);

		goto out;
	}

	/* EC=ESL=1 case */
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	if (cpu_has_feature(CPU_FTR_P9_TM_XER_SO_BUG)) {
		local_paca->requested_psscr = psscr;
		/* order setting requested_psscr vs testing dont_stop */
		smp_mb();
		if (atomic_read(&local_paca->dont_stop)) {
			local_paca->requested_psscr = 0;
			return 0;
		}
	}
#endif

	if (!cpu_has_feature(CPU_FTR_POWER9_DD2_1)) {
		 /*
		  * POWER9 DD2 can incorrectly set PMAO when waking up
		  * after a state-loss idle. Saving and restoring MMCR0
		  * over idle is a workaround.
		  */
		mmcr0		= mfspr(SPRN_MMCR0);
	}
	if ((psscr & PSSCR_RL_MASK) >= pnv_first_spr_loss_level) {
		sprs.lpcr	= mfspr(SPRN_LPCR);
		sprs.hfscr	= mfspr(SPRN_HFSCR);
		sprs.fscr	= mfspr(SPRN_FSCR);
		sprs.pid	= mfspr(SPRN_PID);
		sprs.purr	= mfspr(SPRN_PURR);
		sprs.spurr	= mfspr(SPRN_SPURR);
		sprs.dscr	= mfspr(SPRN_DSCR);
		sprs.wort	= mfspr(SPRN_WORT);

		sprs.mmcra	= mfspr(SPRN_MMCRA);
		sprs.mmcr0	= mfspr(SPRN_MMCR0);
		sprs.mmcr1	= mfspr(SPRN_MMCR1);
		sprs.mmcr2	= mfspr(SPRN_MMCR2);

		sprs.ptcr	= mfspr(SPRN_PTCR);
		sprs.rpr	= mfspr(SPRN_RPR);
		sprs.tscr	= mfspr(SPRN_TSCR);
		if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
			sprs.ldbar = mfspr(SPRN_LDBAR);

		sprs_saved = true;

		atomic_start_thread_idle();
	}

	sprs.amr	= mfspr(SPRN_AMR);
	sprs.iamr	= mfspr(SPRN_IAMR);
	sprs.amor	= mfspr(SPRN_AMOR);
	sprs.uamor	= mfspr(SPRN_UAMOR);

	srr1 = isa300_idle_stop_mayloss(psscr);		/* go idle */

#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	local_paca->requested_psscr = 0;
#endif

	psscr = mfspr(SPRN_PSSCR);

	WARN_ON_ONCE(!srr1);
	WARN_ON_ONCE(mfmsr() & (MSR_IR|MSR_DR));

	if ((srr1 & SRR1_WAKESTATE) != SRR1_WS_NOLOSS) {
		unsigned long mmcra;

		/*
		 * We don't need an isync after the mtsprs here because the
		 * upcoming mtmsrd is execution synchronizing.
		 */
		mtspr(SPRN_AMR,		sprs.amr);
		mtspr(SPRN_IAMR,	sprs.iamr);
		mtspr(SPRN_AMOR,	sprs.amor);
		mtspr(SPRN_UAMOR,	sprs.uamor);

		/*
		 * Workaround for POWER9 DD2.0, if we lost resources, the ERAT
		 * might have been corrupted and needs flushing. We also need
		 * to reload MMCR0 (see mmcr0 comment above).
		 */
		if (!cpu_has_feature(CPU_FTR_POWER9_DD2_1)) {
			asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT);
			mtspr(SPRN_MMCR0, mmcr0);
		}

		/*
		 * DD2.2 and earlier need to set then clear bit 60 in MMCRA
		 * to ensure the PMU starts running.
		 */
		mmcra = mfspr(SPRN_MMCRA);
		mmcra |= PPC_BIT(60);
		mtspr(SPRN_MMCRA, mmcra);
		mmcra &= ~PPC_BIT(60);
		mtspr(SPRN_MMCRA, mmcra);
	}

	if (unlikely((srr1 & SRR1_WAKEMASK_P8) == SRR1_WAKEHMI))
		hmi_exception_realmode(NULL);

	/*
	 * On POWER9, SRR1 bits do not match exactly as expected.
	 * SRR1_WS_GPRLOSS (10b) can also result in SPR loss, so
	 * just always test PSSCR for SPR/TB state loss.
	 */
	pls = (psscr & PSSCR_PLS) >> PSSCR_PLS_SHIFT;
	if (likely(pls < pnv_first_spr_loss_level)) {
		if (sprs_saved)
			atomic_stop_thread_idle();
		goto out;
	}

	/* HV state loss */
	BUG_ON(!sprs_saved);

	atomic_lock_thread_idle();

	if ((*state & core_thread_mask) != 0)
		goto core_woken;

	/* Per-core SPRs */
	mtspr(SPRN_PTCR,	sprs.ptcr);
	mtspr(SPRN_RPR,		sprs.rpr);
	mtspr(SPRN_TSCR,	sprs.tscr);

	if (pls >= pnv_first_tb_loss_level) {
		/* TB loss */
		if (opal_resync_timebase() != OPAL_SUCCESS)
			BUG();
	}

	/*
	 * isync after restoring shared SPRs and before unlocking. Unlock
	 * only contains hwsync which does not necessarily do the right
	 * thing for SPRs.
	 */
	isync();

core_woken:
	atomic_unlock_and_stop_thread_idle();

	/* Per-thread SPRs */
	mtspr(SPRN_LPCR,	sprs.lpcr);
	mtspr(SPRN_HFSCR,	sprs.hfscr);
	mtspr(SPRN_FSCR,	sprs.fscr);
	mtspr(SPRN_PID,		sprs.pid);
	mtspr(SPRN_PURR,	sprs.purr);
	mtspr(SPRN_SPURR,	sprs.spurr);
	mtspr(SPRN_DSCR,	sprs.dscr);
	mtspr(SPRN_WORT,	sprs.wort);

	mtspr(SPRN_MMCRA,	sprs.mmcra);
	mtspr(SPRN_MMCR0,	sprs.mmcr0);
	mtspr(SPRN_MMCR1,	sprs.mmcr1);
	mtspr(SPRN_MMCR2,	sprs.mmcr2);
	if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
		mtspr(SPRN_LDBAR, sprs.ldbar);

	mtspr(SPRN_SPRG3,	local_paca->sprg_vdso);

	if (!radix_enabled())
		__slb_restore_bolted_realmode();

out:
	if (mmu_on)
		mtmsr(MSR_KERNEL);

	return srr1;
}

#ifdef CONFIG_HOTPLUG_CPU
static unsigned long power9_offline_stop(unsigned long psscr)
{
	unsigned long srr1;

#ifndef CONFIG_KVM_BOOK3S_HV_POSSIBLE
	__ppc64_runlatch_off();
	srr1 = power9_idle_stop(psscr, true);
	__ppc64_runlatch_on();
#else
	/*
	 * Tell KVM we're entering idle.
	 * This does not have to be done in real mode because the P9 MMU
	 * is independent per-thread. Some steppings share radix/hash mode
	 * between threads, but in that case KVM has a barrier sync in real
	 * mode before and after switching between radix and hash.
	 *
	 * kvm_start_guest must still be called in real mode though, hence
	 * the false argument.
	 */
	local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_IDLE;

	__ppc64_runlatch_off();
	srr1 = power9_idle_stop(psscr, false);
	__ppc64_runlatch_on();

	local_paca->kvm_hstate.hwthread_state = KVM_HWTHREAD_IN_KERNEL;
	/* Order setting hwthread_state vs. testing hwthread_req */
	smp_mb();
	if (local_paca->kvm_hstate.hwthread_req)
		srr1 = idle_kvm_start_guest(srr1);
	mtmsr(MSR_KERNEL);
#endif

	return srr1;
}
#endif

void power9_idle_type(unsigned long stop_psscr_val,
				      unsigned long stop_psscr_mask)
{
	unsigned long psscr;
	unsigned long srr1;

	if (!prep_irq_for_idle_irqsoff())
		return;

	psscr = mfspr(SPRN_PSSCR);
	psscr = (psscr & ~stop_psscr_mask) | stop_psscr_val;

	__ppc64_runlatch_off();
	srr1 = power9_idle_stop(psscr, true);
	__ppc64_runlatch_on();

	fini_irq_for_idle_irqsoff();

	irq_set_pending_from_srr1(srr1);
}

/*
 * Used for ppc_md.power_save which needs a function with no parameters
 */
void power9_idle(void)
{
	power9_idle_type(pnv_default_stop_val, pnv_default_stop_mask);
}

#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
/*
 * This is used in working around bugs in thread reconfiguration
 * on POWER9 (at least up to Nimbus DD2.2) relating to transactional
 * memory and the way that XER[SO] is checkpointed.
 * This function forces the core into SMT4 in order by asking
 * all other threads not to stop, and sending a message to any
 * that are in a stop state.
 * Must be called with preemption disabled.
 */
void pnv_power9_force_smt4_catch(void)
{
	int cpu, cpu0, thr;
	int awake_threads = 1;		/* this thread is awake */
	int poke_threads = 0;
	int need_awake = threads_per_core;

	cpu = smp_processor_id();
	cpu0 = cpu & ~(threads_per_core - 1);
	for (thr = 0; thr < threads_per_core; ++thr) {
		if (cpu != cpu0 + thr)
			atomic_inc(&paca_ptrs[cpu0+thr]->dont_stop);
	}
	/* order setting dont_stop vs testing requested_psscr */
	smp_mb();
	for (thr = 0; thr < threads_per_core; ++thr) {
		if (!paca_ptrs[cpu0+thr]->requested_psscr)
			++awake_threads;
		else
			poke_threads |= (1 << thr);
	}

	/* If at least 3 threads are awake, the core is in SMT4 already */
	if (awake_threads < need_awake) {
		/* We have to wake some threads; we'll use msgsnd */
		for (thr = 0; thr < threads_per_core; ++thr) {
			if (poke_threads & (1 << thr)) {
				ppc_msgsnd_sync();
				ppc_msgsnd(PPC_DBELL_MSGTYPE, 0,
					   paca_ptrs[cpu0+thr]->hw_cpu_id);
			}
		}
		/* now spin until at least 3 threads are awake */
		do {
			for (thr = 0; thr < threads_per_core; ++thr) {
				if ((poke_threads & (1 << thr)) &&
				    !paca_ptrs[cpu0+thr]->requested_psscr) {
					++awake_threads;
					poke_threads &= ~(1 << thr);
				}
			}
		} while (awake_threads < need_awake);
	}
}
EXPORT_SYMBOL_GPL(pnv_power9_force_smt4_catch);

void pnv_power9_force_smt4_release(void)
{
	int cpu, cpu0, thr;

	cpu = smp_processor_id();
	cpu0 = cpu & ~(threads_per_core - 1);

	/* clear all the dont_stop flags */
	for (thr = 0; thr < threads_per_core; ++thr) {
		if (cpu != cpu0 + thr)
			atomic_dec(&paca_ptrs[cpu0+thr]->dont_stop);
	}
}
EXPORT_SYMBOL_GPL(pnv_power9_force_smt4_release);
#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */

#ifdef CONFIG_HOTPLUG_CPU

void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val)
{
	u64 pir = get_hard_smp_processor_id(cpu);

	mtspr(SPRN_LPCR, lpcr_val);

	/*
	 * Program the LPCR via stop-api only if the deepest stop state
	 * can lose hypervisor context.
	 */
	if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT)
		opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val);
}

/*
 * 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;

	__ppc64_runlatch_off();

	if (cpu_has_feature(CPU_FTR_ARCH_300) && deepest_stop_found) {
		unsigned long psscr;

		psscr = mfspr(SPRN_PSSCR);
		psscr = (psscr & ~pnv_deepest_stop_psscr_mask) |
						pnv_deepest_stop_psscr_val;
		srr1 = power9_offline_stop(psscr);
	} else if (cpu_has_feature(CPU_FTR_ARCH_206) && power7_offline_type) {
		srr1 = power7_offline();
	} else {
		/* This is the fallback method. We emulate snooze */
		while (!generic_check_cpu_restart(cpu)) {
			HMT_low();
			HMT_very_low();
		}
		srr1 = 0;
		HMT_medium();
	}

	__ppc64_runlatch_on();

	return srr1;
}
#endif

/*
 * Power ISA 3.0 idle initialization.
 *
 * POWER ISA 3.0 defines a new SPR Processor stop Status and Control
 * Register (PSSCR) to control idle behavior.
 *
 * PSSCR layout:
 * ----------------------------------------------------------
 * | PLS | /// | SD | ESL | EC | PSLL | /// | TR | MTL | RL |
 * ----------------------------------------------------------
 * 0      4     41   42    43   44     48    54   56    60
 *
 * PSSCR key fields:
 *	Bits 0:3  - Power-Saving Level Status (PLS). This field indicates the
 *	lowest power-saving state the thread entered since stop instruction was
 *	last executed.
 *
 *	Bit 41 - Status Disable(SD)
 *	0 - Shows PLS entries
 *	1 - PLS entries are all 0
 *
 *	Bit 42 - Enable State Loss
 *	0 - No state is lost irrespective of other fields
 *	1 - Allows state loss
 *
 *	Bit 43 - Exit Criterion
 *	0 - Exit from power-save mode on any interrupt
 *	1 - Exit from power-save mode controlled by LPCR's PECE bits
 *
 *	Bits 44:47 - Power-Saving Level Limit
 *	This limits the power-saving level that can be entered into.
 *
 *	Bits 60:63 - Requested Level
 *	Used to specify which power-saving level must be entered on executing
 *	stop instruction
 */

int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags)
{
	int err = 0;

	/*
	 * psscr_mask == 0xf indicates an older firmware.
	 * Set remaining fields of psscr to the default values.
	 * See NOTE above definition of PSSCR_HV_DEFAULT_VAL
	 */
	if (*psscr_mask == 0xf) {
		*psscr_val = *psscr_val | PSSCR_HV_DEFAULT_VAL;
		*psscr_mask = PSSCR_HV_DEFAULT_MASK;
		return err;
	}

	/*
	 * New firmware is expected to set the psscr_val bits correctly.
	 * Validate that the following invariants are correctly maintained by
	 * the new firmware.
	 * - ESL bit value matches the EC bit value.
	 * - ESL bit is set for all the deep stop states.
	 */
	if (GET_PSSCR_ESL(*psscr_val) != GET_PSSCR_EC(*psscr_val)) {
		err = ERR_EC_ESL_MISMATCH;
	} else if ((flags & OPAL_PM_LOSE_FULL_CONTEXT) &&
		GET_PSSCR_ESL(*psscr_val) == 0) {
		err = ERR_DEEP_STATE_ESL_MISMATCH;
	}

	return err;
}

/*
 * pnv_arch300_idle_init: Initializes the default idle state, first
 *                        deep idle state and deepest idle state on
 *                        ISA 3.0 CPUs.
 *
 * @np: /ibm,opal/power-mgt device node
 * @flags: cpu-idle-state-flags array
 * @dt_idle_states: Number of idle state entries
 * Returns 0 on success
 */
static void __init pnv_power9_idle_init(void)
{
	u64 max_residency_ns = 0;
	int i;

	/*
	 * pnv_deepest_stop_{val,mask} should be set to values corresponding to
	 * the deepest stop state.
	 *
	 * pnv_default_stop_{val,mask} should be set to values corresponding to
	 * the deepest loss-less (OPAL_PM_STOP_INST_FAST) stop state.
	 */
	pnv_first_tb_loss_level = MAX_STOP_STATE + 1;
	pnv_first_spr_loss_level = MAX_STOP_STATE + 1;
	for (i = 0; i < nr_pnv_idle_states; i++) {
		int err;
		struct pnv_idle_states_t *state = &pnv_idle_states[i];
		u64 psscr_rl = state->psscr_val & PSSCR_RL_MASK;

		if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
		     (pnv_first_tb_loss_level > psscr_rl))
			pnv_first_tb_loss_level = psscr_rl;

		if ((state->flags & OPAL_PM_LOSE_FULL_CONTEXT) &&
		     (pnv_first_spr_loss_level > psscr_rl))
			pnv_first_spr_loss_level = psscr_rl;

		/*
		 * The idle code does not deal with TB loss occurring
		 * in a shallower state than SPR loss, so force it to
		 * behave like SPRs are lost if TB is lost. POWER9 would
		 * never encouter this, but a POWER8 core would if it
		 * implemented the stop instruction. So this is for forward
		 * compatibility.
		 */
		if ((state->flags & OPAL_PM_TIMEBASE_STOP) &&
		     (pnv_first_spr_loss_level > psscr_rl))
			pnv_first_spr_loss_level = psscr_rl;

		err = validate_psscr_val_mask(&state->psscr_val,
					      &state->psscr_mask,
					      state->flags);
		if (err) {
			report_invalid_psscr_val(state->psscr_val, err);
			continue;
		}

		state->valid = true;

		if (max_residency_ns < state->residency_ns) {
			max_residency_ns = state->residency_ns;
			pnv_deepest_stop_psscr_val = state->psscr_val;
			pnv_deepest_stop_psscr_mask = state->psscr_mask;
			pnv_deepest_stop_flag = state->flags;
			deepest_stop_found = true;
		}

		if (!default_stop_found &&
		    (state->flags & OPAL_PM_STOP_INST_FAST)) {
			pnv_default_stop_val = state->psscr_val;
			pnv_default_stop_mask = state->psscr_mask;
			default_stop_found = true;
			WARN_ON(state->flags & OPAL_PM_LOSE_FULL_CONTEXT);
		}
	}

	if (unlikely(!default_stop_found)) {
		pr_warn("cpuidle-powernv: No suitable default stop state found. Disabling platform idle.\n");
	} else {
		ppc_md.power_save = power9_idle;
		pr_info("cpuidle-powernv: Default stop: psscr = 0x%016llx,mask=0x%016llx\n",
			pnv_default_stop_val, pnv_default_stop_mask);
	}

	if (unlikely(!deepest_stop_found)) {
		pr_warn("cpuidle-powernv: No suitable stop state for CPU-Hotplug. Offlined CPUs will busy wait");
	} else {
		pr_info("cpuidle-powernv: Deepest stop: psscr = 0x%016llx,mask=0x%016llx\n",
			pnv_deepest_stop_psscr_val,
			pnv_deepest_stop_psscr_mask);
	}

	pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%llx\n",
		pnv_first_spr_loss_level);

	pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%llx\n",
		pnv_first_tb_loss_level);
}

static void __init pnv_disable_deep_states(void)
{
	/*
	 * The stop-api is unable to restore hypervisor
	 * resources on wakeup from platform idle states which
	 * lose full context. So disable such states.
	 */
	supported_cpuidle_states &= ~OPAL_PM_LOSE_FULL_CONTEXT;
	pr_warn("cpuidle-powernv: Disabling idle states that lose full context\n");
	pr_warn("cpuidle-powernv: Idle power-savings, CPU-Hotplug affected\n");

	if (cpu_has_feature(CPU_FTR_ARCH_300) &&
	    (pnv_deepest_stop_flag & OPAL_PM_LOSE_FULL_CONTEXT)) {
		/*
		 * Use the default stop state for CPU-Hotplug
		 * if available.
		 */
		if (default_stop_found) {
			pnv_deepest_stop_psscr_val = pnv_default_stop_val;
			pnv_deepest_stop_psscr_mask = pnv_default_stop_mask;
			pr_warn("cpuidle-powernv: Offlined CPUs will stop with psscr = 0x%016llx\n",
				pnv_deepest_stop_psscr_val);
		} else { /* Fallback to snooze loop for CPU-Hotplug */
			deepest_stop_found = false;
			pr_warn("cpuidle-powernv: Offlined CPUs will busy wait\n");
		}
	}
}

/*
 * Probe device tree for supported idle states
 */
static void __init pnv_probe_idle_states(void)
{
	int i;

	if (nr_pnv_idle_states < 0) {
		pr_warn("cpuidle-powernv: no idle states found in the DT\n");
		return;
	}

	if (cpu_has_feature(CPU_FTR_ARCH_300))
		pnv_power9_idle_init();

	for (i = 0; i < nr_pnv_idle_states; i++)
		supported_cpuidle_states |= pnv_idle_states[i].flags;
}

/*
 * This function parses device-tree and populates all the information
 * into pnv_idle_states structure. It also sets up nr_pnv_idle_states
 * which is the number of cpuidle states discovered through device-tree.
 */

static int pnv_parse_cpuidle_dt(void)
{
	struct device_node *np;
	int nr_idle_states, i;
	int rc = 0;
	u32 *temp_u32;
	u64 *temp_u64;
	const char **temp_string;

	np = of_find_node_by_path("/ibm,opal/power-mgt");
	if (!np) {
		pr_warn("opal: PowerMgmt Node not found\n");
		return -ENODEV;
	}
	nr_idle_states = of_property_count_u32_elems(np,
						"ibm,cpu-idle-state-flags");

	pnv_idle_states = kcalloc(nr_idle_states, sizeof(*pnv_idle_states),
				  GFP_KERNEL);
	temp_u32 = kcalloc(nr_idle_states, sizeof(u32),  GFP_KERNEL);
	temp_u64 = kcalloc(nr_idle_states, sizeof(u64),  GFP_KERNEL);
	temp_string = kcalloc(nr_idle_states, sizeof(char *),  GFP_KERNEL);

	if (!(pnv_idle_states && temp_u32 && temp_u64 && temp_string)) {
		pr_err("Could not allocate memory for dt parsing\n");
		rc = -ENOMEM;
		goto out;
	}

	/* Read flags */
	if (of_property_read_u32_array(np, "ibm,cpu-idle-state-flags",
				       temp_u32, nr_idle_states)) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-flags in DT\n");
		rc = -EINVAL;
		goto out;
	}
	for (i = 0; i < nr_idle_states; i++)
		pnv_idle_states[i].flags = temp_u32[i];

	/* Read latencies */
	if (of_property_read_u32_array(np, "ibm,cpu-idle-state-latencies-ns",
				       temp_u32, nr_idle_states)) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n");
		rc = -EINVAL;
		goto out;
	}
	for (i = 0; i < nr_idle_states; i++)
		pnv_idle_states[i].latency_ns = temp_u32[i];

	/* Read residencies */
	if (of_property_read_u32_array(np, "ibm,cpu-idle-state-residency-ns",
				       temp_u32, nr_idle_states)) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n");
		rc = -EINVAL;
		goto out;
	}
	for (i = 0; i < nr_idle_states; i++)
		pnv_idle_states[i].residency_ns = temp_u32[i];

	/* For power9 */
	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
		/* Read pm_crtl_val */
		if (of_property_read_u64_array(np, "ibm,cpu-idle-state-psscr",
					       temp_u64, nr_idle_states)) {
			pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr in DT\n");
			rc = -EINVAL;
			goto out;
		}
		for (i = 0; i < nr_idle_states; i++)
			pnv_idle_states[i].psscr_val = temp_u64[i];

		/* Read pm_crtl_mask */
		if (of_property_read_u64_array(np, "ibm,cpu-idle-state-psscr-mask",
					       temp_u64, nr_idle_states)) {
			pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr-mask in DT\n");
			rc = -EINVAL;
			goto out;
		}
		for (i = 0; i < nr_idle_states; i++)
			pnv_idle_states[i].psscr_mask = temp_u64[i];
	}

	/*
	 * power8 specific properties ibm,cpu-idle-state-pmicr-mask and
	 * ibm,cpu-idle-state-pmicr-val were never used and there is no
	 * plan to use it in near future. Hence, not parsing these properties
	 */

	if (of_property_read_string_array(np, "ibm,cpu-idle-state-names",
					  temp_string, nr_idle_states) < 0) {
		pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-names in DT\n");
		rc = -EINVAL;
		goto out;
	}
	for (i = 0; i < nr_idle_states; i++)
		strlcpy(pnv_idle_states[i].name, temp_string[i],
			PNV_IDLE_NAME_LEN);
	nr_pnv_idle_states = nr_idle_states;
	rc = 0;
out:
	kfree(temp_u32);
	kfree(temp_u64);
	kfree(temp_string);
	return rc;
}

static int __init pnv_init_idle_states(void)
{
	int cpu;
	int rc = 0;

	/* Set up PACA fields */
	for_each_present_cpu(cpu) {
		struct paca_struct *p = paca_ptrs[cpu];

		p->idle_state = 0;
		if (cpu == cpu_first_thread_sibling(cpu))
			p->idle_state = (1 << threads_per_core) - 1;

		if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
			/* P7/P8 nap */
			p->thread_idle_state = PNV_THREAD_RUNNING;
		} else {
			/* P9 stop */
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
			p->requested_psscr = 0;
			atomic_set(&p->dont_stop, 0);
#endif
		}
	}

	/* In case we error out nr_pnv_idle_states will be zero */
	nr_pnv_idle_states = 0;
	supported_cpuidle_states = 0;

	if (cpuidle_disable != IDLE_NO_OVERRIDE)
		goto out;
	rc = pnv_parse_cpuidle_dt();
	if (rc)
		return rc;
	pnv_probe_idle_states();

	if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
		if (!(supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
			power7_fastsleep_workaround_entry = false;
			power7_fastsleep_workaround_exit = false;
		} else {
			/*
			 * OPAL_PM_SLEEP_ENABLED_ER1 is set. It indicates that
			 * workaround is needed to use fastsleep. Provide sysfs
			 * control to choose how this workaround has to be
			 * applied.
			 */
			device_create_file(cpu_subsys.dev_root,
				&dev_attr_fastsleep_workaround_applyonce);
		}

		update_subcore_sibling_mask();

		if (supported_cpuidle_states & OPAL_PM_NAP_ENABLED) {
			ppc_md.power_save = power7_idle;
			power7_offline_type = PNV_THREAD_NAP;
		}

		if ((supported_cpuidle_states & OPAL_PM_WINKLE_ENABLED) &&
			   (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT))
			power7_offline_type = PNV_THREAD_WINKLE;
		else if ((supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED) ||
			   (supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1))
			power7_offline_type = PNV_THREAD_SLEEP;
	}

	if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) {
		if (pnv_save_sprs_for_deep_states())
			pnv_disable_deep_states();
	}

out:
	return 0;
}
machine_subsys_initcall(powernv, pnv_init_idle_states);
