aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bus/arm-ccn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bus/arm-ccn.c')
-rw-r--r--drivers/bus/arm-ccn.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
index 6f550d9e7a2d..a60f26400705 100644
--- a/drivers/bus/arm-ccn.c
+++ b/drivers/bus/arm-ccn.c
@@ -586,6 +586,30 @@ static int arm_ccn_pmu_type_eq(u32 a, u32 b)
586 return 0; 586 return 0;
587} 587}
588 588
589static void arm_ccn_pmu_event_destroy(struct perf_event *event)
590{
591 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
592 struct hw_perf_event *hw = &event->hw;
593
594 if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) {
595 clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask);
596 } else {
597 struct arm_ccn_component *source =
598 ccn->dt.pmu_counters[hw->idx].source;
599
600 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP &&
601 CCN_CONFIG_EVENT(event->attr.config) ==
602 CCN_EVENT_WATCHPOINT)
603 clear_bit(hw->config_base, source->xp.dt_cmp_mask);
604 else
605 clear_bit(hw->config_base, source->pmu_events_mask);
606 clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
607 }
608
609 ccn->dt.pmu_counters[hw->idx].source = NULL;
610 ccn->dt.pmu_counters[hw->idx].event = NULL;
611}
612
589static int arm_ccn_pmu_event_init(struct perf_event *event) 613static int arm_ccn_pmu_event_init(struct perf_event *event)
590{ 614{
591 struct arm_ccn *ccn; 615 struct arm_ccn *ccn;
@@ -599,6 +623,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
599 return -ENOENT; 623 return -ENOENT;
600 624
601 ccn = pmu_to_arm_ccn(event->pmu); 625 ccn = pmu_to_arm_ccn(event->pmu);
626 event->destroy = arm_ccn_pmu_event_destroy;
602 627
603 if (hw->sample_period) { 628 if (hw->sample_period) {
604 dev_warn(ccn->dev, "Sampling not supported!\n"); 629 dev_warn(ccn->dev, "Sampling not supported!\n");
@@ -731,30 +756,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
731 return 0; 756 return 0;
732} 757}
733 758
734static void arm_ccn_pmu_event_free(struct perf_event *event)
735{
736 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
737 struct hw_perf_event *hw = &event->hw;
738
739 if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) {
740 clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask);
741 } else {
742 struct arm_ccn_component *source =
743 ccn->dt.pmu_counters[hw->idx].source;
744
745 if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP &&
746 CCN_CONFIG_EVENT(event->attr.config) ==
747 CCN_EVENT_WATCHPOINT)
748 clear_bit(hw->config_base, source->xp.dt_cmp_mask);
749 else
750 clear_bit(hw->config_base, source->pmu_events_mask);
751 clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
752 }
753
754 ccn->dt.pmu_counters[hw->idx].source = NULL;
755 ccn->dt.pmu_counters[hw->idx].event = NULL;
756}
757
758static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx) 759static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx)
759{ 760{
760 u64 res; 761 u64 res;
@@ -1027,8 +1028,6 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
1027static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) 1028static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)
1028{ 1029{
1029 arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); 1030 arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE);
1030
1031 arm_ccn_pmu_event_free(event);
1032} 1031}
1033 1032
1034static void arm_ccn_pmu_event_read(struct perf_event *event) 1033static void arm_ccn_pmu_event_read(struct perf_event *event)