aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuzuki K Poulose <suzuki.poulose@arm.com>2018-07-10 04:57:59 -0400
committerWill Deacon <will.deacon@arm.com>2018-07-10 13:19:02 -0400
commit3a95200d3f89afd8b67f39d88d36cc7ec96ce385 (patch)
treeceb9428b912eedf3731f71b7a2d7014f57473e4f
parent8d3e994241e6bcc7ead2b918c4f15b7683afa90a (diff)
arm_pmu: Change API to support 64bit counter values
Convert the {read/write}_counter APIs to handle 64bit values to enable supporting chained event counters. The backends still use 32bit values and we pass them 32bit values only. So in effect there are no functional changes. Cc: Will Deacon <will.deacon@arm.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Julien Thierry <julien.thierry@arm.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm/kernel/perf_event_v6.c4
-rw-r--r--arch/arm/kernel/perf_event_v7.c4
-rw-r--r--arch/arm/kernel/perf_event_xscale.c8
-rw-r--r--arch/arm64/kernel/perf_event.c9
-rw-r--r--include/linux/perf/arm_pmu.h4
5 files changed, 14 insertions, 15 deletions
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index f64a6bfebcec..0729f9841ef4 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -233,7 +233,7 @@ armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
233 return ret; 233 return ret;
234} 234}
235 235
236static inline u32 armv6pmu_read_counter(struct perf_event *event) 236static inline u64 armv6pmu_read_counter(struct perf_event *event)
237{ 237{
238 struct hw_perf_event *hwc = &event->hw; 238 struct hw_perf_event *hwc = &event->hw;
239 int counter = hwc->idx; 239 int counter = hwc->idx;
@@ -251,7 +251,7 @@ static inline u32 armv6pmu_read_counter(struct perf_event *event)
251 return value; 251 return value;
252} 252}
253 253
254static inline void armv6pmu_write_counter(struct perf_event *event, u32 value) 254static inline void armv6pmu_write_counter(struct perf_event *event, u64 value)
255{ 255{
256 struct hw_perf_event *hwc = &event->hw; 256 struct hw_perf_event *hwc = &event->hw;
257 int counter = hwc->idx; 257 int counter = hwc->idx;
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 2cf1ca2925c8..973043dd6187 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -743,7 +743,7 @@ static inline void armv7_pmnc_select_counter(int idx)
743 isb(); 743 isb();
744} 744}
745 745
746static inline u32 armv7pmu_read_counter(struct perf_event *event) 746static inline u64 armv7pmu_read_counter(struct perf_event *event)
747{ 747{
748 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 748 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
749 struct hw_perf_event *hwc = &event->hw; 749 struct hw_perf_event *hwc = &event->hw;
@@ -763,7 +763,7 @@ static inline u32 armv7pmu_read_counter(struct perf_event *event)
763 return value; 763 return value;
764} 764}
765 765
766static inline void armv7pmu_write_counter(struct perf_event *event, u32 value) 766static inline void armv7pmu_write_counter(struct perf_event *event, u64 value)
767{ 767{
768 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 768 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
769 struct hw_perf_event *hwc = &event->hw; 769 struct hw_perf_event *hwc = &event->hw;
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index c4f029458b52..942230fe0426 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -316,7 +316,7 @@ static void xscale1pmu_stop(struct arm_pmu *cpu_pmu)
316 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 316 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
317} 317}
318 318
319static inline u32 xscale1pmu_read_counter(struct perf_event *event) 319static inline u64 xscale1pmu_read_counter(struct perf_event *event)
320{ 320{
321 struct hw_perf_event *hwc = &event->hw; 321 struct hw_perf_event *hwc = &event->hw;
322 int counter = hwc->idx; 322 int counter = hwc->idx;
@@ -337,7 +337,7 @@ static inline u32 xscale1pmu_read_counter(struct perf_event *event)
337 return val; 337 return val;
338} 338}
339 339
340static inline void xscale1pmu_write_counter(struct perf_event *event, u32 val) 340static inline void xscale1pmu_write_counter(struct perf_event *event, u64 val)
341{ 341{
342 struct hw_perf_event *hwc = &event->hw; 342 struct hw_perf_event *hwc = &event->hw;
343 int counter = hwc->idx; 343 int counter = hwc->idx;
@@ -678,7 +678,7 @@ static void xscale2pmu_stop(struct arm_pmu *cpu_pmu)
678 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 678 raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
679} 679}
680 680
681static inline u32 xscale2pmu_read_counter(struct perf_event *event) 681static inline u64 xscale2pmu_read_counter(struct perf_event *event)
682{ 682{
683 struct hw_perf_event *hwc = &event->hw; 683 struct hw_perf_event *hwc = &event->hw;
684 int counter = hwc->idx; 684 int counter = hwc->idx;
@@ -705,7 +705,7 @@ static inline u32 xscale2pmu_read_counter(struct perf_event *event)
705 return val; 705 return val;
706} 706}
707 707
708static inline void xscale2pmu_write_counter(struct perf_event *event, u32 val) 708static inline void xscale2pmu_write_counter(struct perf_event *event, u64 val)
709{ 709{
710 struct hw_perf_event *hwc = &event->hw; 710 struct hw_perf_event *hwc = &event->hw;
711 int counter = hwc->idx; 711 int counter = hwc->idx;
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 678ecffd3724..66a2ffdca6dd 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -512,7 +512,7 @@ static inline int armv8pmu_select_counter(int idx)
512 return idx; 512 return idx;
513} 513}
514 514
515static inline u32 armv8pmu_read_counter(struct perf_event *event) 515static inline u64 armv8pmu_read_counter(struct perf_event *event)
516{ 516{
517 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 517 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
518 struct hw_perf_event *hwc = &event->hw; 518 struct hw_perf_event *hwc = &event->hw;
@@ -530,7 +530,7 @@ static inline u32 armv8pmu_read_counter(struct perf_event *event)
530 return value; 530 return value;
531} 531}
532 532
533static inline void armv8pmu_write_counter(struct perf_event *event, u32 value) 533static inline void armv8pmu_write_counter(struct perf_event *event, u64 value)
534{ 534{
535 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); 535 struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
536 struct hw_perf_event *hwc = &event->hw; 536 struct hw_perf_event *hwc = &event->hw;
@@ -545,9 +545,8 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
545 * count using the lower 32bits and we want an interrupt when 545 * count using the lower 32bits and we want an interrupt when
546 * it overflows. 546 * it overflows.
547 */ 547 */
548 u64 value64 = 0xffffffff00000000ULL | value; 548 value |= 0xffffffff00000000ULL;
549 549 write_sysreg(value, pmccntr_el0);
550 write_sysreg(value64, pmccntr_el0);
551 } else if (armv8pmu_select_counter(idx) == idx) 550 } else if (armv8pmu_select_counter(idx) == idx)
552 write_sysreg(value, pmxevcntr_el0); 551 write_sysreg(value, pmxevcntr_el0);
553} 552}
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 12c30a22fc8d..f7126a21df30 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -87,8 +87,8 @@ struct arm_pmu {
87 struct perf_event *event); 87 struct perf_event *event);
88 int (*set_event_filter)(struct hw_perf_event *evt, 88 int (*set_event_filter)(struct hw_perf_event *evt,
89 struct perf_event_attr *attr); 89 struct perf_event_attr *attr);
90 u32 (*read_counter)(struct perf_event *event); 90 u64 (*read_counter)(struct perf_event *event);
91 void (*write_counter)(struct perf_event *event, u32 val); 91 void (*write_counter)(struct perf_event *event, u64 val);
92 void (*start)(struct arm_pmu *); 92 void (*start)(struct arm_pmu *);
93 void (*stop)(struct arm_pmu *); 93 void (*stop)(struct arm_pmu *);
94 void (*reset)(void *); 94 void (*reset)(void *);