Perf: Save and restore counters through powercollapse

Update the active perf counter data structs with the most recent
values of the counters before going into powercollapse and restore
the corresponding hardware counters with these values when coming
out of it.

This change fixes a bug where the counter outputs show wild swings
when CPU power collapse is enabled.

Change-Id: I9c4ff4d4504df5b50c33a796c605126448c440cb
Signed-off-by: Ashwin Chaugule <ashwinc@codeaurora.org>
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index b59ad93..6a7158b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -247,7 +247,6 @@
 	/* Don't read disabled counters! */
 	if (hwc->idx < 0)
 		return;
-
 	armpmu_event_update(event, hwc, hwc->idx, 0);
 }
 
@@ -632,6 +631,24 @@
 		armpmu->stop();
 }
 
+static void armpmu_update_counters(void)
+{
+	int idx;
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	if (!armpmu)
+		return;
+
+	for (idx = 0; idx <= armpmu->num_events; ++idx) {
+		struct perf_event *event = cpuc->events[idx];
+
+		if (!event)
+			continue;
+
+		armpmu_read(event);
+	}
+}
+
 static struct pmu pmu = {
 	.pmu_enable	= armpmu_enable,
 	.pmu_disable	= armpmu_disable,
@@ -657,6 +674,7 @@
 {
 	switch (cmd) {
 	case CPU_PM_ENTER:
+		armpmu_update_counters();
 		perf_pmu_disable(&pmu);
 		break;