diff options
Diffstat (limited to 'drivers/bus/arm-ccn.c')
| -rw-r--r-- | drivers/bus/arm-ccn.c | 53 | 
1 files changed, 26 insertions, 27 deletions
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c index 3266f8ff9311..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)  	return 0;  } +static void arm_ccn_pmu_event_destroy(struct perf_event *event) +{ +	struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); +	struct hw_perf_event *hw = &event->hw; + +	if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) { +		clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask); +	} else { +		struct arm_ccn_component *source = +				ccn->dt.pmu_counters[hw->idx].source; + +		if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP && +				CCN_CONFIG_EVENT(event->attr.config) == +				CCN_EVENT_WATCHPOINT) +			clear_bit(hw->config_base, source->xp.dt_cmp_mask); +		else +			clear_bit(hw->config_base, source->pmu_events_mask); +		clear_bit(hw->idx, ccn->dt.pmu_counters_mask); +	} + +	ccn->dt.pmu_counters[hw->idx].source = NULL; +	ccn->dt.pmu_counters[hw->idx].event = NULL; +} +  static int arm_ccn_pmu_event_init(struct perf_event *event)  {  	struct arm_ccn *ccn; @@ -599,6 +623,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)  		return -ENOENT;  	ccn = pmu_to_arm_ccn(event->pmu); +	event->destroy = arm_ccn_pmu_event_destroy;  	if (hw->sample_period) {  		dev_warn(ccn->dev, "Sampling not supported!\n"); @@ -662,7 +687,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)  		}  		if (e->num_vcs && vc >= e->num_vcs) {  			dev_warn(ccn->dev, "Invalid vc %d for node/XP %d!\n", -					port, node_xp); +					vc, node_xp);  			return -EINVAL;  		}  		valid = 1; @@ -731,30 +756,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)  	return 0;  } -static void arm_ccn_pmu_event_free(struct perf_event *event) -{ -	struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); -	struct hw_perf_event *hw = &event->hw; - -	if (hw->idx == CCN_IDX_PMU_CYCLE_COUNTER) { -		clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask); -	} else { -		struct arm_ccn_component *source = -				ccn->dt.pmu_counters[hw->idx].source; - -		if (CCN_CONFIG_TYPE(event->attr.config) == CCN_TYPE_XP && -				CCN_CONFIG_EVENT(event->attr.config) == -				CCN_EVENT_WATCHPOINT) -			clear_bit(hw->config_base, source->xp.dt_cmp_mask); -		else -			clear_bit(hw->config_base, source->pmu_events_mask); -		clear_bit(hw->idx, ccn->dt.pmu_counters_mask); -	} - -	ccn->dt.pmu_counters[hw->idx].source = NULL; -	ccn->dt.pmu_counters[hw->idx].event = NULL; -} -  static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx)  {  	u64 res; @@ -1027,8 +1028,6 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)  static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)  {  	arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE); - -	arm_ccn_pmu_event_free(event);  }  static void arm_ccn_pmu_event_read(struct perf_event *event)  |