mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
powerpc/powernv/idle: Disable LOSE_FULL_CONTEXT states when stop-api fails
Currently, we use the opal call opal_slw_set_reg() to inform the
Sleep-Winkle Engine (SLW) to restore the contents of some of the
Hypervisor state on wakeup from deep idle states that lose full
hypervisor context (characterized by the flag
OPAL_PM_LOSE_FULL_CONTEXT).
However, the current code has a bug in that if opal_slw_set_reg()
fails, we don't disable the use of these deep states (winkle on
POWER8, stop4 onwards on POWER9).
This patch fixes this bug by ensuring that if programing the
sleep-winkle engine to restore the hypervisor states in
pnv_save_sprs_for_deep_states() fails, then we exclude such states by
clearing the OPAL_PM_LOSE_FULL_CONTEXT flag from
supported_cpuidle_states. As a result POWER8 will be prevented from
using winkle for CPU-Hotplug, and POWER9 will put the offlined CPUs to
the default stop state when available.
Further, we ensure in the initialization of the cpuidle-powernv driver
to only include those states whose flags are present in
supported_cpuidle_states, thereby skipping OPAL_PM_LOSE_FULL_CONTEXT
states when they have been disabled due to stop-api failure.
Fixes: 1e1601b38e ("powerpc/powernv/idle: Restore SPRs for deep idle
states via stop API.")
Signed-off-by: Gautham R. Shenoy <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
This commit is contained in:
parent
44a12806d0
commit
785a12afdb
2 changed files with 48 additions and 3 deletions
|
|
@ -235,6 +235,7 @@ static inline int validate_dt_prop_sizes(const char *prop1, int prop1_len,
|
|||
return -1;
|
||||
}
|
||||
|
||||
extern u32 pnv_get_supported_cpuidle_states(void);
|
||||
static int powernv_add_idle_states(void)
|
||||
{
|
||||
struct device_node *power_mgt;
|
||||
|
|
@ -248,6 +249,8 @@ static int powernv_add_idle_states(void)
|
|||
const char *names[CPUIDLE_STATE_MAX];
|
||||
u32 has_stop_states = 0;
|
||||
int i, rc;
|
||||
u32 supported_flags = pnv_get_supported_cpuidle_states();
|
||||
|
||||
|
||||
/* Currently we have snooze statically defined */
|
||||
|
||||
|
|
@ -362,6 +365,13 @@ 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;
|
||||
|
||||
/*
|
||||
* Skip the platform idle state whose flag isn't in
|
||||
* the supported_cpuidle_states flag mask.
|
||||
*/
|
||||
if ((flags[i] & supported_flags) != flags[i])
|
||||
continue;
|
||||
/*
|
||||
* If an idle state has exit latency beyond
|
||||
* POWERNV_THRESHOLD_LATENCY_NS then don't use it
|
||||
|
|
|
|||
Loading…
Reference in a new issue