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);
 };