ARM: perf: lock PMU registers per-CPU
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / kernel / perf_event_xscale.c
index 54312fc45ca3c85aaf35a5539e0f14c4684e3702..18e4823a0a62967163c7a2f3ce90ef8dbfe85ecc 100644 (file)
@@ -253,9 +253,6 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
                struct perf_event *event = cpuc->events[idx];
                struct hw_perf_event *hwc;
 
-               if (!test_bit(idx, cpuc->active_mask))
-                       continue;
-
                if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
                        continue;
 
@@ -284,6 +281,7 @@ static void
 xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
 {
        unsigned long val, mask, evt, flags;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
        switch (idx) {
        case XSCALE_CYCLE_COUNTER:
@@ -305,18 +303,19 @@ xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
                return;
        }
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale1pmu_read_pmnc();
        val &= ~mask;
        val |= evt;
        xscale1pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static void
 xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
 {
        unsigned long val, mask, evt, flags;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
        switch (idx) {
        case XSCALE_CYCLE_COUNTER:
@@ -336,12 +335,12 @@ xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
                return;
        }
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale1pmu_read_pmnc();
        val &= ~mask;
        val |= evt;
        xscale1pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static int
@@ -368,24 +367,26 @@ static void
 xscale1pmu_start(void)
 {
        unsigned long flags, val;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale1pmu_read_pmnc();
        val |= XSCALE_PMU_ENABLE;
        xscale1pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static void
 xscale1pmu_stop(void)
 {
        unsigned long flags, val;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale1pmu_read_pmnc();
        val &= ~XSCALE_PMU_ENABLE;
        xscale1pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static inline u32
@@ -585,9 +586,6 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
                struct perf_event *event = cpuc->events[idx];
                struct hw_perf_event *hwc;
 
-               if (!test_bit(idx, cpuc->active_mask))
-                       continue;
-
                if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
                        continue;
 
@@ -616,6 +614,7 @@ static void
 xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
 {
        unsigned long flags, ien, evtsel;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
        ien = xscale2pmu_read_int_enable();
        evtsel = xscale2pmu_read_event_select();
@@ -649,16 +648,17 @@ xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
                return;
        }
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        xscale2pmu_write_event_select(evtsel);
        xscale2pmu_write_int_enable(ien);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static void
 xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
 {
        unsigned long flags, ien, evtsel;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
        ien = xscale2pmu_read_int_enable();
        evtsel = xscale2pmu_read_event_select();
@@ -692,10 +692,10 @@ xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
                return;
        }
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        xscale2pmu_write_event_select(evtsel);
        xscale2pmu_write_int_enable(ien);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static int
@@ -718,24 +718,26 @@ static void
 xscale2pmu_start(void)
 {
        unsigned long flags, val;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
        val |= XSCALE_PMU_ENABLE;
        xscale2pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static void
 xscale2pmu_stop(void)
 {
        unsigned long flags, val;
+       struct cpu_hw_events *events = armpmu->get_hw_events();
 
-       raw_spin_lock_irqsave(&pmu_lock, flags);
+       raw_spin_lock_irqsave(&events->pmu_lock, flags);
        val = xscale2pmu_read_pmnc();
        val &= ~XSCALE_PMU_ENABLE;
        xscale2pmu_write_pmnc(val);
-       raw_spin_unlock_irqrestore(&pmu_lock, flags);
+       raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
 }
 
 static inline u32