Perf: Re-enable counters after power collapse

Counters need to be individually re-enabled after the CPU
comes out of power collapse. Without this the counters
will simply be set to their MAX period and starting the PMU
will have no effect.

Change-Id: I3988a45277057eb80cf580b90ce697d0e6a00c43
Signed-off-by: Ashwin Chaugule <ashwinc@codeaurora.org>
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 37cbfcb..0d0103a 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -108,6 +108,12 @@
 	enum arm_pmu_type type;
 	cpumask_t	active_irqs;
 	const char	*name;
+	int		num_events;
+	atomic_t	active_events;
+	struct mutex	reserve_mutex;
+	u64		max_period;
+	struct platform_device	*plat_device;
+	u32		from_idle;
 	irqreturn_t	(*handle_irq)(int irq_num, void *dev);
 	int     	(*request_pmu_irq)(int irq, irq_handler_t *irq_h);
 	void    	(*free_pmu_irq)(int irq);
@@ -123,11 +129,6 @@
 	void		(*stop)(void);
 	void		(*reset)(void *);
 	int		(*map_event)(struct perf_event *event);
-	int		num_events;
-	atomic_t	active_events;
-	struct mutex	reserve_mutex;
-	u64		max_period;
-	struct platform_device	*plat_device;
 	struct pmu_hw_events	*(*get_hw_events)(void);
 	int	(*test_set_event_constraints)(struct perf_event *event);
 	int	(*clear_event_constraints)(struct perf_event *event);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 778128b..e97aef2 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -600,6 +600,21 @@
 	struct arm_pmu *armpmu = to_arm_pmu(pmu);
 	struct pmu_hw_events *hw_events = armpmu->get_hw_events();
 	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+	int idx;
+
+	if (armpmu->from_idle) {
+		for (idx = 0; idx <= cpu_pmu->num_events; ++idx) {
+			struct perf_event *event = hw_events->events[idx];
+
+			if (!event)
+				continue;
+
+			armpmu->enable(&event->hw, idx, event->cpu);
+		}
+
+		/* Reset bit so we don't needlessly re-enable counters.*/
+		armpmu->from_idle = 0;
+	}
 
 	if (enabled)
 		armpmu->start();
@@ -716,6 +731,7 @@
  * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
  * junk values out of them.
  */
+
 static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
 					unsigned long action, void *hcpu)
 {
@@ -785,6 +801,11 @@
 	case CPU_PM_ENTER_FAILED:
 	case CPU_PM_EXIT:
 		if (cpu_has_active_perf() && cpu_pmu->reset) {
+			/*
+			 * Flip this bit so armpmu_enable knows it needs
+			 * to re-enable active counters.
+			 */
+			cpu_pmu->from_idle = 1;
 			cpu_pmu->reset(NULL);
 			perf_pmu_enable(&cpu_pmu->pmu);
 		}