drivers: cpuidle: lpm_levels: Correctly update lpm stats
Correctly update LPM stats for cluster level to indicate
success. Update system_pm_ops as well to use correct exit
status for rpmh master stats update.
Change-Id: Ia50dcb21cd041db0ed17d25897fe346afe06dab2
Signed-off-by: Maulik Shah <mkshah@codeaurora.org>
diff --git a/drivers/cpuidle/lpm-levels-legacy.c b/drivers/cpuidle/lpm-levels-legacy.c
index 26cb52a..4e94876 100644
--- a/drivers/cpuidle/lpm-levels-legacy.c
+++ b/drivers/cpuidle/lpm-levels-legacy.c
@@ -100,7 +100,7 @@
static void cluster_unprepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
- int64_t time);
+ int64_t time, bool success);
static void cluster_prepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
int64_t time);
@@ -736,7 +736,7 @@
static void cluster_unprepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
- int64_t end_time)
+ int64_t end_time, bool success)
{
struct lpm_cluster_level *level;
bool first_cpu;
@@ -769,12 +769,12 @@
if (cluster->stats->sleep_time)
cluster->stats->sleep_time = end_time -
cluster->stats->sleep_time;
- lpm_stats_cluster_exit(cluster->stats, cluster->last_level, true);
+ lpm_stats_cluster_exit(cluster->stats, cluster->last_level, success);
level = &cluster->levels[cluster->last_level];
if (level->notify_rpm) {
if (sys_pm_ops && sys_pm_ops->exit)
- sys_pm_ops->exit();
+ sys_pm_ops->exit(success);
/* If RPM bumps up CX to turbo, unvote CX turbo vote
* during exit of rpm assisted power collapse to
@@ -807,7 +807,7 @@
cluster_notify(cluster, &cluster->levels[last_level], false);
cluster_unprepare(cluster->parent, &cluster->child_cpus,
- last_level, from_idle, end_time);
+ last_level, from_idle, end_time, success);
unlock_return:
spin_unlock(&cluster->sync_lock);
}
@@ -1039,7 +1039,7 @@
end_time = ktime_to_ns(ktime_get());
lpm_stats_cpu_exit(idx, end_time, success);
- cluster_unprepare(cluster, cpumask, idx, true, end_time);
+ cluster_unprepare(cluster, cpumask, idx, true, end_time, success);
cpu_unprepare(cluster, idx, true);
trace_cpu_idle_exit(idx, success);
@@ -1248,6 +1248,7 @@
struct lpm_cpu *lpm_cpu = cluster->cpu;
const struct cpumask *cpumask = get_cpu_mask(cpu);
int idx;
+ bool success = true;
for (idx = lpm_cpu->nlevels - 1; idx >= 0; idx--) {
@@ -1275,13 +1276,13 @@
if (!use_psci)
msm_cpu_pm_enter_sleep(cluster->cpu->levels[idx].mode, false);
else
- psci_enter_sleep(cluster, idx, true);
+ success = psci_enter_sleep(cluster, idx, true);
if (idx > 0)
update_debug_pc_event(CPU_EXIT, idx, true, 0xdeaffeed,
false);
- cluster_unprepare(cluster, cpumask, idx, false, 0);
+ cluster_unprepare(cluster, cpumask, idx, false, 0, success);
cpu_unprepare(cluster, idx, false);
return 0;
}
@@ -1304,7 +1305,8 @@
update_debug_pc_event(CPU_HP_STARTING, cpu,
cluster->num_children_in_sync.bits[0],
cluster->child_cpus.bits[0], false);
- cluster_unprepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS, false, 0);
+ cluster_unprepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS,
+ false, 0, true);
return 0;
}
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index ae72206..fdf2888 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -117,7 +117,7 @@
static void cluster_unprepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
- int64_t time);
+ int64_t time, bool success);
static void cluster_prepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
int64_t time);
@@ -328,7 +328,8 @@
update_debug_pc_event(CPU_HP_STARTING, cpu,
cluster->num_children_in_sync.bits[0],
cluster->child_cpus.bits[0], false);
- cluster_unprepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS, false, 0);
+ cluster_unprepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS, false,
+ 0, true);
return 0;
}
@@ -1165,7 +1166,7 @@
static void cluster_unprepare(struct lpm_cluster *cluster,
const struct cpumask *cpu, int child_idx, bool from_idle,
- int64_t end_time)
+ int64_t end_time, bool success)
{
struct lpm_cluster_level *level;
bool first_cpu;
@@ -1202,14 +1203,14 @@
if (cluster->stats->sleep_time)
cluster->stats->sleep_time = end_time -
cluster->stats->sleep_time;
- lpm_stats_cluster_exit(cluster->stats, cluster->last_level, true);
+ lpm_stats_cluster_exit(cluster->stats, cluster->last_level, success);
level = &cluster->levels[cluster->last_level];
if (level->notify_rpm)
if (sys_pm_ops && sys_pm_ops->exit) {
spin_lock(&bc_timer_lock);
- sys_pm_ops->exit();
+ sys_pm_ops->exit(success);
spin_unlock(&bc_timer_lock);
}
@@ -1229,7 +1230,7 @@
update_cluster_history(&cluster->history, last_level);
cluster_unprepare(cluster->parent, &cluster->child_cpus,
- last_level, from_idle, end_time);
+ last_level, from_idle, end_time, success);
unlock_return:
spin_unlock(&cluster->sync_lock);
}
@@ -1423,7 +1424,7 @@
end_time = ktime_to_ns(ktime_get());
lpm_stats_cpu_exit(idx, end_time, success);
- cluster_unprepare(cpu->parent, cpumask, idx, true, end_time);
+ cluster_unprepare(cpu->parent, cpumask, idx, true, end_time, success);
cpu_unprepare(cpu, idx, true);
dev->last_residency = ktime_us_delta(ktime_get(), start);
update_history(dev, idx);
@@ -1441,6 +1442,7 @@
{
struct lpm_cpu *cpu = per_cpu(cpu_lpm, dev->cpu);
const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
+ bool success = false;
for (; idx >= 0; idx--) {
if (lpm_cpu_mode_allow(dev->cpu, idx, false))
@@ -1454,9 +1456,9 @@
cpu_prepare(cpu, idx, true);
cluster_prepare(cpu->parent, cpumask, idx, false, 0);
- psci_enter_sleep(cpu, idx, false);
+ success = psci_enter_sleep(cpu, idx, false);
- cluster_unprepare(cpu->parent, cpumask, idx, false, 0);
+ cluster_unprepare(cpu->parent, cpumask, idx, false, 0, success);
cpu_unprepare(cpu, idx, true);
}
@@ -1671,6 +1673,7 @@
struct lpm_cluster *cluster = lpm_cpu->parent;
const struct cpumask *cpumask = get_cpu_mask(cpu);
int idx;
+ bool success;
for (idx = lpm_cpu->nlevels - 1; idx >= 0; idx--) {
if (lpm_cpu_mode_allow(cpu, idx, false))
@@ -1683,9 +1686,9 @@
cpu_prepare(lpm_cpu, idx, false);
cluster_prepare(cluster, cpumask, idx, false, 0);
- psci_enter_sleep(lpm_cpu, idx, false);
+ success = psci_enter_sleep(lpm_cpu, idx, false);
- cluster_unprepare(cluster, cpumask, idx, false, 0);
+ cluster_unprepare(cluster, cpumask, idx, false, 0, success);
cpu_unprepare(lpm_cpu, idx, false);
return 0;
}
diff --git a/drivers/irqchip/qcom/mpm.c b/drivers/irqchip/qcom/mpm.c
index 5e352f4..813b6b3 100644
--- a/drivers/irqchip/qcom/mpm.c
+++ b/drivers/irqchip/qcom/mpm.c
@@ -417,7 +417,7 @@
}
-static void system_pm_exit_sleep(void)
+static void system_pm_exit_sleep(bool success)
{
msm_rpm_exit_sleep();
}
diff --git a/drivers/soc/qcom/system_pm.c b/drivers/soc/qcom/system_pm.c
index 9ef685b..e65f0b7 100644
--- a/drivers/soc/qcom/system_pm.c
+++ b/drivers/soc/qcom/system_pm.c
@@ -75,9 +75,10 @@
/**
* system_sleep_exit() - Activities done when exiting system low power modes
*/
-static void system_sleep_exit(void)
+static void system_sleep_exit(bool success)
{
- msm_rpmh_master_stats_update();
+ if (success)
+ msm_rpmh_master_stats_update();
gic_v3_dist_restore();
}
diff --git a/include/soc/qcom/lpm_levels.h b/include/soc/qcom/lpm_levels.h
index 3665caf..7104ed5 100644
--- a/include/soc/qcom/lpm_levels.h
+++ b/include/soc/qcom/lpm_levels.h
@@ -15,7 +15,7 @@
struct system_pm_ops {
int (*enter)(struct cpumask *mask);
- void (*exit)(void);
+ void (*exit)(bool success);
int (*update_wakeup)(bool);
bool (*sleep_allowed)(void);
};