This patch sets up flags for the state which needs to be auto-promoted. For powernv systems, lite states do not even lose user context. That information has been used to set the flag for lite states.
Signed-off-by: Abhishek Goel <hunt...@linux.vnet.ibm.com> --- arch/powerpc/include/asm/opal-api.h | 1 + drivers/cpuidle/Kconfig | 4 ++++ drivers/cpuidle/cpuidle-powernv.c | 13 +++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 870fb7b23..735dec731 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -226,6 +226,7 @@ */ #define OPAL_PM_TIMEBASE_STOP 0x00000002 +#define OPAL_PM_LOSE_USER_CONTEXT 0x00001000 #define OPAL_PM_LOSE_HYP_CONTEXT 0x00002000 #define OPAL_PM_LOSE_FULL_CONTEXT 0x00004000 #define OPAL_PM_NAP_ENABLED 0x00010000 diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index 7e48eb5bf..0ece62684 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -26,6 +26,10 @@ config CPU_IDLE_GOV_MENU config DT_IDLE_STATES bool +config CPU_IDLE_AUTO_PROMOTION + bool + default y if PPC_POWERNV + menu "ARM CPU Idle Drivers" depends on ARM || ARM64 source "drivers/cpuidle/Kconfig.arm" diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 84b1ebe21..e351f5f9c 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -299,6 +299,7 @@ static int powernv_add_idle_states(void) for (i = 0; i < dt_idle_states; i++) { unsigned int exit_latency, target_residency; bool stops_timebase = false; + bool lose_user_context = false; struct pnv_idle_states_t *state = &pnv_idle_states[i]; /* @@ -324,6 +325,9 @@ static int powernv_add_idle_states(void) if (has_stop_states && !(state->valid)) continue; + if (state->flags & OPAL_PM_LOSE_USER_CONTEXT) + lose_user_context = true; + if (state->flags & OPAL_PM_TIMEBASE_STOP) stops_timebase = true; @@ -332,12 +336,17 @@ static int powernv_add_idle_states(void) add_powernv_state(nr_idle_states, "Nap", CPUIDLE_FLAG_NONE, nap_loop, target_residency, exit_latency, 0, 0); + } else if (has_stop_states & !lose_user_context) { + add_powernv_state(nr_idle_states, state->name, + CPUIDLE_FLAG_AUTO_PROMOTION, + stop_loop, target_residency, + exit_latency, state->psscr_val, + state->psscr_mask); } else if (has_stop_states && !stops_timebase) { add_powernv_state(nr_idle_states, state->name, CPUIDLE_FLAG_NONE, stop_loop, target_residency, exit_latency, - state->psscr_val, - state->psscr_mask); + state->psscr_val, state->psscr_mask); } /* -- 2.17.1