diff options
| -rw-r--r-- | drivers/bus/arm-ccn.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c index c826bb286054..12c1fd1bc398 100644 --- a/drivers/bus/arm-ccn.c +++ b/drivers/bus/arm-ccn.c | |||
| @@ -940,15 +940,6 @@ static void arm_ccn_pmu_event_start(struct perf_event *event, int flags) | |||
| 940 | arm_ccn_pmu_read_counter(ccn, hw->idx)); | 940 | arm_ccn_pmu_read_counter(ccn, hw->idx)); |
| 941 | hw->state = 0; | 941 | hw->state = 0; |
| 942 | 942 | ||
| 943 | /* | ||
| 944 | * Pin the timer, so that the overflows are handled by the chosen | ||
| 945 | * event->cpu (this is the same one as presented in "cpumask" | ||
| 946 | * attribute). | ||
| 947 | */ | ||
| 948 | if (!ccn->irq) | ||
| 949 | hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(), | ||
| 950 | HRTIMER_MODE_REL_PINNED); | ||
| 951 | |||
| 952 | /* Set the DT bus input, engaging the counter */ | 943 | /* Set the DT bus input, engaging the counter */ |
| 953 | arm_ccn_pmu_xp_dt_config(event, 1); | 944 | arm_ccn_pmu_xp_dt_config(event, 1); |
| 954 | } | 945 | } |
| @@ -962,9 +953,6 @@ static void arm_ccn_pmu_event_stop(struct perf_event *event, int flags) | |||
| 962 | /* Disable counting, setting the DT bus to pass-through mode */ | 953 | /* Disable counting, setting the DT bus to pass-through mode */ |
| 963 | arm_ccn_pmu_xp_dt_config(event, 0); | 954 | arm_ccn_pmu_xp_dt_config(event, 0); |
| 964 | 955 | ||
| 965 | if (!ccn->irq) | ||
| 966 | hrtimer_cancel(&ccn->dt.hrtimer); | ||
| 967 | |||
| 968 | /* Let the DT bus drain */ | 956 | /* Let the DT bus drain */ |
| 969 | timeout = arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) + | 957 | timeout = arm_ccn_pmu_read_counter(ccn, CCN_IDX_PMU_CYCLE_COUNTER) + |
| 970 | ccn->num_xps; | 958 | ccn->num_xps; |
| @@ -1122,15 +1110,31 @@ static void arm_ccn_pmu_event_config(struct perf_event *event) | |||
| 1122 | spin_unlock(&ccn->dt.config_lock); | 1110 | spin_unlock(&ccn->dt.config_lock); |
| 1123 | } | 1111 | } |
| 1124 | 1112 | ||
| 1113 | static int arm_ccn_pmu_active_counters(struct arm_ccn *ccn) | ||
| 1114 | { | ||
| 1115 | return bitmap_weight(ccn->dt.pmu_counters_mask, | ||
| 1116 | CCN_NUM_PMU_EVENT_COUNTERS + 1); | ||
| 1117 | } | ||
| 1118 | |||
| 1125 | static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) | 1119 | static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) |
| 1126 | { | 1120 | { |
| 1127 | int err; | 1121 | int err; |
| 1128 | struct hw_perf_event *hw = &event->hw; | 1122 | struct hw_perf_event *hw = &event->hw; |
| 1123 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
| 1129 | 1124 | ||
| 1130 | err = arm_ccn_pmu_event_alloc(event); | 1125 | err = arm_ccn_pmu_event_alloc(event); |
| 1131 | if (err) | 1126 | if (err) |
| 1132 | return err; | 1127 | return err; |
| 1133 | 1128 | ||
| 1129 | /* | ||
| 1130 | * Pin the timer, so that the overflows are handled by the chosen | ||
| 1131 | * event->cpu (this is the same one as presented in "cpumask" | ||
| 1132 | * attribute). | ||
| 1133 | */ | ||
| 1134 | if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 1) | ||
| 1135 | hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(), | ||
| 1136 | HRTIMER_MODE_REL_PINNED); | ||
| 1137 | |||
| 1134 | arm_ccn_pmu_event_config(event); | 1138 | arm_ccn_pmu_event_config(event); |
| 1135 | 1139 | ||
| 1136 | hw->state = PERF_HES_STOPPED; | 1140 | hw->state = PERF_HES_STOPPED; |
| @@ -1143,9 +1147,14 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags) | |||
| 1143 | 1147 | ||
| 1144 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) | 1148 | static void arm_ccn_pmu_event_del(struct perf_event *event, int flags) |
| 1145 | { | 1149 | { |
| 1150 | struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); | ||
| 1151 | |||
| 1146 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); | 1152 | arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); |
| 1147 | 1153 | ||
| 1148 | arm_ccn_pmu_event_release(event); | 1154 | arm_ccn_pmu_event_release(event); |
| 1155 | |||
| 1156 | if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 0) | ||
| 1157 | hrtimer_cancel(&ccn->dt.hrtimer); | ||
| 1149 | } | 1158 | } |
| 1150 | 1159 | ||
| 1151 | static void arm_ccn_pmu_event_read(struct perf_event *event) | 1160 | static void arm_ccn_pmu_event_read(struct perf_event *event) |
