diff options
Diffstat (limited to 'arch/arm/kernel/perf_event_v7.c')
-rw-r--r-- | arch/arm/kernel/perf_event_v7.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 2e1402556fa0..4960686afb58 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c | |||
@@ -466,6 +466,7 @@ static inline unsigned long armv7_pmnc_read(void) | |||
466 | static inline void armv7_pmnc_write(unsigned long val) | 466 | static inline void armv7_pmnc_write(unsigned long val) |
467 | { | 467 | { |
468 | val &= ARMV7_PMNC_MASK; | 468 | val &= ARMV7_PMNC_MASK; |
469 | isb(); | ||
469 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); | 470 | asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); |
470 | } | 471 | } |
471 | 472 | ||
@@ -502,6 +503,7 @@ static inline int armv7_pmnc_select_counter(unsigned int idx) | |||
502 | 503 | ||
503 | val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; | 504 | val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; |
504 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); | 505 | asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); |
506 | isb(); | ||
505 | 507 | ||
506 | return idx; | 508 | return idx; |
507 | } | 509 | } |
@@ -780,7 +782,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) | |||
780 | continue; | 782 | continue; |
781 | 783 | ||
782 | hwc = &event->hw; | 784 | hwc = &event->hw; |
783 | armpmu_event_update(event, hwc, idx); | 785 | armpmu_event_update(event, hwc, idx, 1); |
784 | data.period = event->hw.last_period; | 786 | data.period = event->hw.last_period; |
785 | if (!armpmu_event_set_period(event, hwc, idx)) | 787 | if (!armpmu_event_set_period(event, hwc, idx)) |
786 | continue; | 788 | continue; |
@@ -847,6 +849,18 @@ static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, | |||
847 | } | 849 | } |
848 | } | 850 | } |
849 | 851 | ||
852 | static void armv7pmu_reset(void *info) | ||
853 | { | ||
854 | u32 idx, nb_cnt = armpmu->num_events; | ||
855 | |||
856 | /* The counter and interrupt enable registers are unknown at reset. */ | ||
857 | for (idx = 1; idx < nb_cnt; ++idx) | ||
858 | armv7pmu_disable_event(NULL, idx); | ||
859 | |||
860 | /* Initialize & Reset PMNC: C and P bits */ | ||
861 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); | ||
862 | } | ||
863 | |||
850 | static struct arm_pmu armv7pmu = { | 864 | static struct arm_pmu armv7pmu = { |
851 | .handle_irq = armv7pmu_handle_irq, | 865 | .handle_irq = armv7pmu_handle_irq, |
852 | .enable = armv7pmu_enable_event, | 866 | .enable = armv7pmu_enable_event, |
@@ -856,17 +870,15 @@ static struct arm_pmu armv7pmu = { | |||
856 | .get_event_idx = armv7pmu_get_event_idx, | 870 | .get_event_idx = armv7pmu_get_event_idx, |
857 | .start = armv7pmu_start, | 871 | .start = armv7pmu_start, |
858 | .stop = armv7pmu_stop, | 872 | .stop = armv7pmu_stop, |
873 | .reset = armv7pmu_reset, | ||
859 | .raw_event_mask = 0xFF, | 874 | .raw_event_mask = 0xFF, |
860 | .max_period = (1LLU << 32) - 1, | 875 | .max_period = (1LLU << 32) - 1, |
861 | }; | 876 | }; |
862 | 877 | ||
863 | static u32 __init armv7_reset_read_pmnc(void) | 878 | static u32 __init armv7_read_num_pmnc_events(void) |
864 | { | 879 | { |
865 | u32 nb_cnt; | 880 | u32 nb_cnt; |
866 | 881 | ||
867 | /* Initialize & Reset PMNC: C and P bits */ | ||
868 | armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); | ||
869 | |||
870 | /* Read the nb of CNTx counters supported from PMNC */ | 882 | /* Read the nb of CNTx counters supported from PMNC */ |
871 | nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; | 883 | nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; |
872 | 884 | ||
@@ -880,7 +892,7 @@ static const struct arm_pmu *__init armv7_a8_pmu_init(void) | |||
880 | armv7pmu.name = "ARMv7 Cortex-A8"; | 892 | armv7pmu.name = "ARMv7 Cortex-A8"; |
881 | armv7pmu.cache_map = &armv7_a8_perf_cache_map; | 893 | armv7pmu.cache_map = &armv7_a8_perf_cache_map; |
882 | armv7pmu.event_map = &armv7_a8_perf_map; | 894 | armv7pmu.event_map = &armv7_a8_perf_map; |
883 | armv7pmu.num_events = armv7_reset_read_pmnc(); | 895 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
884 | return &armv7pmu; | 896 | return &armv7pmu; |
885 | } | 897 | } |
886 | 898 | ||
@@ -890,7 +902,7 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void) | |||
890 | armv7pmu.name = "ARMv7 Cortex-A9"; | 902 | armv7pmu.name = "ARMv7 Cortex-A9"; |
891 | armv7pmu.cache_map = &armv7_a9_perf_cache_map; | 903 | armv7pmu.cache_map = &armv7_a9_perf_cache_map; |
892 | armv7pmu.event_map = &armv7_a9_perf_map; | 904 | armv7pmu.event_map = &armv7_a9_perf_map; |
893 | armv7pmu.num_events = armv7_reset_read_pmnc(); | 905 | armv7pmu.num_events = armv7_read_num_pmnc_events(); |
894 | return &armv7pmu; | 906 | return &armv7pmu; |
895 | } | 907 | } |
896 | #else | 908 | #else |