diff options
author | Hoan Tran <hotran@apm.com> | 2017-06-22 19:26:04 +0100 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2017-06-22 20:16:18 +0100 |
commit | e35e0a04a9965bcb4fffe4375baaecd408ad2357 (patch) | |
tree | 6ccb568a1bebe6955be0538099f32711acbbc655 /drivers/perf | |
parent | 838955e2a3c010aff9089fd705ae2cd5638cdee8 (diff) |
perf: xgene: Move PMU leaf functions into function pointer structure
This patch moves PMU leaf functions into a function pointer structure.
It helps code maintain and expasion easier.
Signed-off-by: Hoan Tran <hotran@apm.com>
[Mark: remove redundant cast]
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
[will: make xgene_pmu_ops static]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/perf')
-rw-r--r-- | drivers/perf/xgene_pmu.c | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c index 5ffd58028a62..53e9e31053d6 100644 --- a/drivers/perf/xgene_pmu.c +++ b/drivers/perf/xgene_pmu.c @@ -96,6 +96,23 @@ struct xgene_pmu_dev { struct perf_event *pmu_counter_event[PMU_MAX_COUNTERS]; }; +struct xgene_pmu_ops { + void (*mask_int)(struct xgene_pmu *pmu); + void (*unmask_int)(struct xgene_pmu *pmu); + u64 (*read_counter)(struct xgene_pmu_dev *pmu, int idx); + void (*write_counter)(struct xgene_pmu_dev *pmu, int idx, u64 val); + void (*write_evttype)(struct xgene_pmu_dev *pmu_dev, int idx, u32 val); + void (*write_agentmsk)(struct xgene_pmu_dev *pmu_dev, u32 val); + void (*write_agent1msk)(struct xgene_pmu_dev *pmu_dev, u32 val); + void (*enable_counter)(struct xgene_pmu_dev *pmu_dev, int idx); + void (*disable_counter)(struct xgene_pmu_dev *pmu_dev, int idx); + void (*enable_counter_int)(struct xgene_pmu_dev *pmu_dev, int idx); + void (*disable_counter_int)(struct xgene_pmu_dev *pmu_dev, int idx); + void (*reset_counters)(struct xgene_pmu_dev *pmu_dev); + void (*start_counters)(struct xgene_pmu_dev *pmu_dev); + void (*stop_counters)(struct xgene_pmu_dev *pmu_dev); +}; + struct xgene_pmu { struct device *dev; int version; @@ -104,6 +121,7 @@ struct xgene_pmu { u32 mc_active_mask; cpumask_t cpu; raw_spinlock_t lock; + const struct xgene_pmu_ops *ops; struct list_head l3cpmus; struct list_head iobpmus; struct list_head mcbpmus; @@ -392,13 +410,14 @@ static inline void xgene_pmu_unmask_int(struct xgene_pmu *xgene_pmu) writel(PCPPMU_INTCLRMASK, xgene_pmu->pcppmu_csr + PCPPMU_INTMASK_REG); } -static inline u32 xgene_pmu_read_counter(struct xgene_pmu_dev *pmu_dev, int idx) +static inline u64 xgene_pmu_read_counter32(struct xgene_pmu_dev *pmu_dev, + int idx) { return readl(pmu_dev->inf->csr + PMU_PMEVCNTR0 + (4 * idx)); } static inline void -xgene_pmu_write_counter(struct xgene_pmu_dev *pmu_dev, int idx, u32 val) +xgene_pmu_write_counter32(struct xgene_pmu_dev *pmu_dev, int idx, u64 val) { writel(val, pmu_dev->inf->csr + PMU_PMEVCNTR0 + (4 * idx)); } @@ -491,20 +510,22 @@ static inline void xgene_pmu_stop_counters(struct xgene_pmu_dev *pmu_dev) static void xgene_perf_pmu_enable(struct pmu *pmu) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; int enabled = bitmap_weight(pmu_dev->cntr_assign_mask, pmu_dev->max_counters); if (!enabled) return; - xgene_pmu_start_counters(pmu_dev); + xgene_pmu->ops->start_counters(pmu_dev); } static void xgene_perf_pmu_disable(struct pmu *pmu) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; - xgene_pmu_stop_counters(pmu_dev); + xgene_pmu->ops->stop_counters(pmu_dev); } static int xgene_perf_event_init(struct perf_event *event) @@ -572,27 +593,32 @@ static int xgene_perf_event_init(struct perf_event *event) static void xgene_perf_enable_event(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; - xgene_pmu_write_evttype(pmu_dev, GET_CNTR(event), GET_EVENTID(event)); - xgene_pmu_write_agentmsk(pmu_dev, ~((u32)GET_AGENTID(event))); + xgene_pmu->ops->write_evttype(pmu_dev, GET_CNTR(event), + GET_EVENTID(event)); + xgene_pmu->ops->write_agentmsk(pmu_dev, ~((u32)GET_AGENTID(event))); if (pmu_dev->inf->type == PMU_TYPE_IOB) - xgene_pmu_write_agent1msk(pmu_dev, ~((u32)GET_AGENT1ID(event))); + xgene_pmu->ops->write_agent1msk(pmu_dev, + ~((u32)GET_AGENT1ID(event))); - xgene_pmu_enable_counter(pmu_dev, GET_CNTR(event)); - xgene_pmu_enable_counter_int(pmu_dev, GET_CNTR(event)); + xgene_pmu->ops->enable_counter(pmu_dev, GET_CNTR(event)); + xgene_pmu->ops->enable_counter_int(pmu_dev, GET_CNTR(event)); } static void xgene_perf_disable_event(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; - xgene_pmu_disable_counter(pmu_dev, GET_CNTR(event)); - xgene_pmu_disable_counter_int(pmu_dev, GET_CNTR(event)); + xgene_pmu->ops->disable_counter(pmu_dev, GET_CNTR(event)); + xgene_pmu->ops->disable_counter_int(pmu_dev, GET_CNTR(event)); } static void xgene_perf_event_set_period(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; struct hw_perf_event *hw = &event->hw; /* * The X-Gene PMU counters have a period of 2^32. To account for the @@ -603,18 +629,19 @@ static void xgene_perf_event_set_period(struct perf_event *event) u64 val = 1ULL << 31; local64_set(&hw->prev_count, val); - xgene_pmu_write_counter(pmu_dev, hw->idx, (u32) val); + xgene_pmu->ops->write_counter(pmu_dev, hw->idx, val); } static void xgene_perf_event_update(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; struct hw_perf_event *hw = &event->hw; u64 delta, prev_raw_count, new_raw_count; again: prev_raw_count = local64_read(&hw->prev_count); - new_raw_count = xgene_pmu_read_counter(pmu_dev, GET_CNTR(event)); + new_raw_count = xgene_pmu->ops->read_counter(pmu_dev, GET_CNTR(event)); if (local64_cmpxchg(&hw->prev_count, prev_raw_count, new_raw_count) != prev_raw_count) @@ -633,6 +660,7 @@ static void xgene_perf_read(struct perf_event *event) static void xgene_perf_start(struct perf_event *event, int flags) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); + struct xgene_pmu *xgene_pmu = pmu_dev->parent; struct hw_perf_event *hw = &event->hw; if (WARN_ON_ONCE(!(hw->state & PERF_HES_STOPPED))) @@ -646,8 +674,8 @@ static void xgene_perf_start(struct perf_event *event, int flags) if (flags & PERF_EF_RELOAD) { u64 prev_raw_count = local64_read(&hw->prev_count); - xgene_pmu_write_counter(pmu_dev, GET_CNTR(event), - (u32) prev_raw_count); + xgene_pmu->ops->write_counter(pmu_dev, GET_CNTR(event), + prev_raw_count); } xgene_perf_enable_event(event); @@ -736,8 +764,8 @@ static int xgene_init_perf(struct xgene_pmu_dev *pmu_dev, char *name) }; /* Hardware counter init */ - xgene_pmu_stop_counters(pmu_dev); - xgene_pmu_reset_counters(pmu_dev); + xgene_pmu->ops->stop_counters(pmu_dev); + xgene_pmu->ops->reset_counters(pmu_dev); return perf_pmu_register(&pmu_dev->pmu, name, -1); } @@ -1255,6 +1283,23 @@ static const struct xgene_pmu_data xgene_pmu_v2_data = { .id = PCP_PMU_V2, }; +static const struct xgene_pmu_ops xgene_pmu_ops = { + .mask_int = xgene_pmu_mask_int, + .unmask_int = xgene_pmu_unmask_int, + .read_counter = xgene_pmu_read_counter32, + .write_counter = xgene_pmu_write_counter32, + .write_evttype = xgene_pmu_write_evttype, + .write_agentmsk = xgene_pmu_write_agentmsk, + .write_agent1msk = xgene_pmu_write_agent1msk, + .enable_counter = xgene_pmu_enable_counter, + .disable_counter = xgene_pmu_disable_counter, + .enable_counter_int = xgene_pmu_enable_counter_int, + .disable_counter_int = xgene_pmu_disable_counter_int, + .reset_counters = xgene_pmu_reset_counters, + .start_counters = xgene_pmu_start_counters, + .stop_counters = xgene_pmu_stop_counters, +}; + static const struct of_device_id xgene_pmu_of_match[] = { { .compatible = "apm,xgene-pmu", .data = &xgene_pmu_data }, { .compatible = "apm,xgene-pmu-v2", .data = &xgene_pmu_v2_data }, @@ -1304,6 +1349,8 @@ static int xgene_pmu_probe(struct platform_device *pdev) if (version < 0) return -ENODEV; + xgene_pmu->ops = &xgene_pmu_ops; + INIT_LIST_HEAD(&xgene_pmu->l3cpmus); INIT_LIST_HEAD(&xgene_pmu->iobpmus); INIT_LIST_HEAD(&xgene_pmu->mcbpmus); @@ -1362,7 +1409,7 @@ static int xgene_pmu_probe(struct platform_device *pdev) } /* Enable interrupt */ - xgene_pmu_unmask_int(xgene_pmu); + xgene_pmu->ops->unmask_int(xgene_pmu); return 0; |