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

Reply via email to