cregit-Linux how code gets into the kernel

Release 4.11 drivers/perf/xgene_pmu.c

Directory: drivers/perf
/*
 * APM X-Gene SoC PMU (Performance Monitor Unit)
 *
 * Copyright (c) 2016, Applied Micro Circuits Corporation
 * Author: Hoan Tran <hotran@apm.com>
 *         Tai Nguyen <ttnguyen@apm.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>


#define CSW_CSWCR                       0x0000

#define  CSW_CSWCR_DUALMCB_MASK         BIT(0)

#define MCBADDRMR                       0x0000

#define  MCBADDRMR_DUALMCU_MODE_MASK    BIT(2)


#define PCPPMU_INTSTATUS_REG	0x000

#define PCPPMU_INTMASK_REG	0x004

#define  PCPPMU_INTMASK		0x0000000F

#define  PCPPMU_INTENMASK	0xFFFFFFFF

#define  PCPPMU_INTCLRMASK	0xFFFFFFF0

#define  PCPPMU_INT_MCU		BIT(0)

#define  PCPPMU_INT_MCB		BIT(1)

#define  PCPPMU_INT_L3C		BIT(2)

#define  PCPPMU_INT_IOB		BIT(3)


#define PMU_MAX_COUNTERS	4

#define PMU_CNT_MAX_PERIOD	0x100000000ULL

#define PMU_OVERFLOW_MASK	0xF

#define PMU_PMCR_E		BIT(0)

#define PMU_PMCR_P		BIT(1)


#define PMU_PMEVCNTR0		0x000

#define PMU_PMEVCNTR1		0x004

#define PMU_PMEVCNTR2		0x008

#define PMU_PMEVCNTR3		0x00C

#define PMU_PMEVTYPER0		0x400

#define PMU_PMEVTYPER1		0x404

#define PMU_PMEVTYPER2		0x408

#define PMU_PMEVTYPER3		0x40C

#define PMU_PMAMR0		0xA00

#define PMU_PMAMR1		0xA04

#define PMU_PMCNTENSET		0xC00

#define PMU_PMCNTENCLR		0xC20

#define PMU_PMINTENSET		0xC40

#define PMU_PMINTENCLR		0xC60

#define PMU_PMOVSR		0xC80

#define PMU_PMCR		0xE04


#define to_pmu_dev(p)     container_of(p, struct xgene_pmu_dev, pmu)

#define GET_CNTR(ev)      (ev->hw.idx)

#define GET_EVENTID(ev)   (ev->hw.config & 0xFFULL)

#define GET_AGENTID(ev)   (ev->hw.config_base & 0xFFFFFFFFUL)

#define GET_AGENT1ID(ev)  ((ev->hw.config_base >> 32) & 0xFFFFFFFFUL)


struct hw_pmu_info {
	
u32 type;
	
u32 enable_mask;
	
void __iomem *csr;
};


struct xgene_pmu_dev {
	
struct hw_pmu_info *inf;
	
struct xgene_pmu *parent;
	
struct pmu pmu;
	
u8 max_counters;
	DECLARE_BITMAP(cntr_assign_mask, PMU_MAX_COUNTERS);
	
u64 max_period;
	
const struct attribute_group **attr_groups;
	
struct perf_event *pmu_counter_event[PMU_MAX_COUNTERS];
};


struct xgene_pmu {
	
struct device *dev;
	
int version;
	
void __iomem *pcppmu_csr;
	
u32 mcb_active_mask;
	
u32 mc_active_mask;
	
cpumask_t cpu;
	
raw_spinlock_t lock;
	
struct list_head l3cpmus;
	
struct list_head iobpmus;
	
struct list_head mcbpmus;
	
struct list_head mcpmus;
};


struct xgene_pmu_dev_ctx {
	
char *name;
	
struct list_head next;
	
struct xgene_pmu_dev *pmu_dev;
	
struct hw_pmu_info inf;
};


struct xgene_pmu_data {
	
int id;
	
u32 data;
};


enum xgene_pmu_version {
	
PCP_PMU_V1 = 1,
	
PCP_PMU_V2,
};


enum xgene_pmu_dev_type {
	
PMU_TYPE_L3C = 0,
	
PMU_TYPE_IOB,
	
PMU_TYPE_MCB,
	
PMU_TYPE_MC,
};

/*
 * sysfs format attributes
 */

static ssize_t xgene_pmu_format_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *eattr; eattr = container_of(attr, struct dev_ext_attribute, attr); return sprintf(buf, "%s\n", (char *) eattr->var); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen53100.00%1100.00%
Total53100.00%1100.00%

#define XGENE_PMU_FORMAT_ATTR(_name, _config) \ (&((struct dev_ext_attribute[]) { \ { .attr = __ATTR(_name, S_IRUGO, xgene_pmu_format_show, NULL), \ .var = (void *) _config, } \ })[0].attr.attr) static struct attribute *l3c_pmu_format_attrs[] = { XGENE_PMU_FORMAT_ATTR(l3c_eventid, "config:0-7"), XGENE_PMU_FORMAT_ATTR(l3c_agentid, "config1:0-9"), NULL, }; static struct attribute *iob_pmu_format_attrs[] = { XGENE_PMU_FORMAT_ATTR(iob_eventid, "config:0-7"), XGENE_PMU_FORMAT_ATTR(iob_agentid, "config1:0-63"), NULL, }; static struct attribute *mcb_pmu_format_attrs[] = { XGENE_PMU_FORMAT_ATTR(mcb_eventid, "config:0-5"), XGENE_PMU_FORMAT_ATTR(mcb_agentid, "config1:0-9"), NULL, }; static struct attribute *mc_pmu_format_attrs[] = { XGENE_PMU_FORMAT_ATTR(mc_eventid, "config:0-28"), NULL, }; static const struct attribute_group l3c_pmu_format_attr_group = { .name = "format", .attrs = l3c_pmu_format_attrs, }; static const struct attribute_group iob_pmu_format_attr_group = { .name = "format", .attrs = iob_pmu_format_attrs, }; static const struct attribute_group mcb_pmu_format_attr_group = { .name = "format", .attrs = mcb_pmu_format_attrs, }; static const struct attribute_group mc_pmu_format_attr_group = { .name = "format", .attrs = mc_pmu_format_attrs, }; /* * sysfs event attributes */
static ssize_t xgene_pmu_event_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *eattr; eattr = container_of(attr, struct dev_ext_attribute, attr); return sprintf(buf, "config=0x%lx\n", (unsigned long) eattr->var); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen53100.00%1100.00%
Total53100.00%1100.00%

#define XGENE_PMU_EVENT_ATTR(_name, _config) \ (&((struct dev_ext_attribute[]) { \ { .attr = __ATTR(_name, S_IRUGO, xgene_pmu_event_show, NULL), \ .var = (void *) _config, } \ })[0].attr.attr) static struct attribute *l3c_pmu_events_attrs[] = { XGENE_PMU_EVENT_ATTR(cycle-count, 0x00), XGENE_PMU_EVENT_ATTR(cycle-count-div-64, 0x01), XGENE_PMU_EVENT_ATTR(read-hit, 0x02), XGENE_PMU_EVENT_ATTR(read-miss, 0x03), XGENE_PMU_EVENT_ATTR(write-need-replacement, 0x06), XGENE_PMU_EVENT_ATTR(write-not-need-replacement, 0x07), XGENE_PMU_EVENT_ATTR(tq-full, 0x08), XGENE_PMU_EVENT_ATTR(ackq-full, 0x09), XGENE_PMU_EVENT_ATTR(wdb-full, 0x0a), XGENE_PMU_EVENT_ATTR(bank-fifo-full, 0x0b), XGENE_PMU_EVENT_ATTR(odb-full, 0x0c), XGENE_PMU_EVENT_ATTR(wbq-full, 0x0d), XGENE_PMU_EVENT_ATTR(bank-conflict-fifo-issue, 0x0e), XGENE_PMU_EVENT_ATTR(bank-fifo-issue, 0x0f), NULL, }; static struct attribute *iob_pmu_events_attrs[] = { XGENE_PMU_EVENT_ATTR(cycle-count, 0x00), XGENE_PMU_EVENT_ATTR(cycle-count-div-64, 0x01), XGENE_PMU_EVENT_ATTR(axi0-read, 0x02), XGENE_PMU_EVENT_ATTR(axi0-read-partial, 0x03), XGENE_PMU_EVENT_ATTR(axi1-read, 0x04), XGENE_PMU_EVENT_ATTR(axi1-read-partial, 0x05), XGENE_PMU_EVENT_ATTR(csw-read-block, 0x06), XGENE_PMU_EVENT_ATTR(csw-read-partial, 0x07), XGENE_PMU_EVENT_ATTR(axi0-write, 0x10), XGENE_PMU_EVENT_ATTR(axi0-write-partial, 0x11), XGENE_PMU_EVENT_ATTR(axi1-write, 0x13), XGENE_PMU_EVENT_ATTR(axi1-write-partial, 0x14), XGENE_PMU_EVENT_ATTR(csw-inbound-dirty, 0x16), NULL, }; static struct attribute *mcb_pmu_events_attrs[] = { XGENE_PMU_EVENT_ATTR(cycle-count, 0x00), XGENE_PMU_EVENT_ATTR(cycle-count-div-64, 0x01), XGENE_PMU_EVENT_ATTR(csw-read, 0x02), XGENE_PMU_EVENT_ATTR(csw-write-request, 0x03), XGENE_PMU_EVENT_ATTR(mcb-csw-stall, 0x04), XGENE_PMU_EVENT_ATTR(cancel-read-gack, 0x05), NULL, }; static struct attribute *mc_pmu_events_attrs[] = { XGENE_PMU_EVENT_ATTR(cycle-count, 0x00), XGENE_PMU_EVENT_ATTR(cycle-count-div-64, 0x01), XGENE_PMU_EVENT_ATTR(act-cmd-sent, 0x02), XGENE_PMU_EVENT_ATTR(pre-cmd-sent, 0x03), XGENE_PMU_EVENT_ATTR(rd-cmd-sent, 0x04), XGENE_PMU_EVENT_ATTR(rda-cmd-sent, 0x05), XGENE_PMU_EVENT_ATTR(wr-cmd-sent, 0x06), XGENE_PMU_EVENT_ATTR(wra-cmd-sent, 0x07), XGENE_PMU_EVENT_ATTR(pde-cmd-sent, 0x08), XGENE_PMU_EVENT_ATTR(sre-cmd-sent, 0x09), XGENE_PMU_EVENT_ATTR(prea-cmd-sent, 0x0a), XGENE_PMU_EVENT_ATTR(ref-cmd-sent, 0x0b), XGENE_PMU_EVENT_ATTR(rd-rda-cmd-sent, 0x0c), XGENE_PMU_EVENT_ATTR(wr-wra-cmd-sent, 0x0d), XGENE_PMU_EVENT_ATTR(in-rd-collision, 0x0e), XGENE_PMU_EVENT_ATTR(in-wr-collision, 0x0f), XGENE_PMU_EVENT_ATTR(collision-queue-not-empty, 0x10), XGENE_PMU_EVENT_ATTR(collision-queue-full, 0x11), XGENE_PMU_EVENT_ATTR(mcu-request, 0x12), XGENE_PMU_EVENT_ATTR(mcu-rd-request, 0x13), XGENE_PMU_EVENT_ATTR(mcu-hp-rd-request, 0x14), XGENE_PMU_EVENT_ATTR(mcu-wr-request, 0x15), XGENE_PMU_EVENT_ATTR(mcu-rd-proceed-all, 0x16), XGENE_PMU_EVENT_ATTR(mcu-rd-proceed-cancel, 0x17), XGENE_PMU_EVENT_ATTR(mcu-rd-response, 0x18), XGENE_PMU_EVENT_ATTR(mcu-rd-proceed-speculative-all, 0x19), XGENE_PMU_EVENT_ATTR(mcu-rd-proceed-speculative-cancel, 0x1a), XGENE_PMU_EVENT_ATTR(mcu-wr-proceed-all, 0x1b), XGENE_PMU_EVENT_ATTR(mcu-wr-proceed-cancel, 0x1c), NULL, }; static const struct attribute_group l3c_pmu_events_attr_group = { .name = "events", .attrs = l3c_pmu_events_attrs, }; static const struct attribute_group iob_pmu_events_attr_group = { .name = "events", .attrs = iob_pmu_events_attrs, }; static const struct attribute_group mcb_pmu_events_attr_group = { .name = "events", .attrs = mcb_pmu_events_attrs, }; static const struct attribute_group mc_pmu_events_attr_group = { .name = "events", .attrs = mc_pmu_events_attrs, }; /* * sysfs cpumask attributes */
static ssize_t xgene_pmu_cpumask_show(struct device *dev, struct device_attribute *attr, char *buf) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(dev_get_drvdata(dev)); return cpumap_print_to_pagebuf(true, buf, &pmu_dev->parent->cpu); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen48100.00%1100.00%
Total48100.00%1100.00%

static DEVICE_ATTR(cpumask, S_IRUGO, xgene_pmu_cpumask_show, NULL); static struct attribute *xgene_pmu_cpumask_attrs[] = { &dev_attr_cpumask.attr, NULL, }; static const struct attribute_group pmu_cpumask_attr_group = { .attrs = xgene_pmu_cpumask_attrs, }; /* * Per PMU device attribute groups */ static const struct attribute_group *l3c_pmu_attr_groups[] = { &l3c_pmu_format_attr_group, &pmu_cpumask_attr_group, &l3c_pmu_events_attr_group, NULL }; static const struct attribute_group *iob_pmu_attr_groups[] = { &iob_pmu_format_attr_group, &pmu_cpumask_attr_group, &iob_pmu_events_attr_group, NULL }; static const struct attribute_group *mcb_pmu_attr_groups[] = { &mcb_pmu_format_attr_group, &pmu_cpumask_attr_group, &mcb_pmu_events_attr_group, NULL }; static const struct attribute_group *mc_pmu_attr_groups[] = { &mc_pmu_format_attr_group, &pmu_cpumask_attr_group, &mc_pmu_events_attr_group, NULL };
static int get_next_avail_cntr(struct xgene_pmu_dev *pmu_dev) { int cntr; cntr = find_first_zero_bit(pmu_dev->cntr_assign_mask, pmu_dev->max_counters); if (cntr == pmu_dev->max_counters) return -ENOSPC; set_bit(cntr, pmu_dev->cntr_assign_mask); return cntr; }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen51100.00%1100.00%
Total51100.00%1100.00%


static void clear_avail_cntr(struct xgene_pmu_dev *pmu_dev, int cntr) { clear_bit(cntr, pmu_dev->cntr_assign_mask); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen23100.00%1100.00%
Total23100.00%1100.00%


static inline void xgene_pmu_mask_int(struct xgene_pmu *xgene_pmu) { writel(PCPPMU_INTENMASK, xgene_pmu->pcppmu_csr + PCPPMU_INTMASK_REG); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen23100.00%1100.00%
Total23100.00%1100.00%


static inline void xgene_pmu_unmask_int(struct xgene_pmu *xgene_pmu) { writel(PCPPMU_INTCLRMASK, xgene_pmu->pcppmu_csr + PCPPMU_INTMASK_REG); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen23100.00%1100.00%
Total23100.00%1100.00%


static inline u32 xgene_pmu_read_counter(struct xgene_pmu_dev *pmu_dev, int idx) { return readl(pmu_dev->inf->csr + PMU_PMEVCNTR0 + (4 * idx)); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen33100.00%1100.00%
Total33100.00%1100.00%


static inline void xgene_pmu_write_counter(struct xgene_pmu_dev *pmu_dev, int idx, u32 val) { writel(val, pmu_dev->inf->csr + PMU_PMEVCNTR0 + (4 * idx)); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen37100.00%1100.00%
Total37100.00%1100.00%


static inline void xgene_pmu_write_evttype(struct xgene_pmu_dev *pmu_dev, int idx, u32 val) { writel(val, pmu_dev->inf->csr + PMU_PMEVTYPER0 + (4 * idx)); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen37100.00%1100.00%
Total37100.00%1100.00%


static inline void xgene_pmu_write_agentmsk(struct xgene_pmu_dev *pmu_dev, u32 val) { writel(val, pmu_dev->inf->csr + PMU_PMAMR0); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen28100.00%1100.00%
Total28100.00%1100.00%


static inline void xgene_pmu_write_agent1msk(struct xgene_pmu_dev *pmu_dev, u32 val) { writel(val, pmu_dev->inf->csr + PMU_PMAMR1); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen28100.00%1100.00%
Total28100.00%1100.00%


static inline void xgene_pmu_enable_counter(struct xgene_pmu_dev *pmu_dev, int idx) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMCNTENSET); val |= 1 << idx; writel(val, pmu_dev->inf->csr + PMU_PMCNTENSET); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen50100.00%1100.00%
Total50100.00%1100.00%


static inline void xgene_pmu_disable_counter(struct xgene_pmu_dev *pmu_dev, int idx) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMCNTENCLR); val |= 1 << idx; writel(val, pmu_dev->inf->csr + PMU_PMCNTENCLR); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen50100.00%1100.00%
Total50100.00%1100.00%


static inline void xgene_pmu_enable_counter_int(struct xgene_pmu_dev *pmu_dev, int idx) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMINTENSET); val |= 1 << idx; writel(val, pmu_dev->inf->csr + PMU_PMINTENSET); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen50100.00%1100.00%
Total50100.00%1100.00%


static inline void xgene_pmu_disable_counter_int(struct xgene_pmu_dev *pmu_dev, int idx) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMINTENCLR); val |= 1 << idx; writel(val, pmu_dev->inf->csr + PMU_PMINTENCLR); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen50100.00%1100.00%
Total50100.00%1100.00%


static inline void xgene_pmu_reset_counters(struct xgene_pmu_dev *pmu_dev) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMCR); val |= PMU_PMCR_P; writel(val, pmu_dev->inf->csr + PMU_PMCR); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen45100.00%1100.00%
Total45100.00%1100.00%


static inline void xgene_pmu_start_counters(struct xgene_pmu_dev *pmu_dev) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMCR); val |= PMU_PMCR_E; writel(val, pmu_dev->inf->csr + PMU_PMCR); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen45100.00%1100.00%
Total45100.00%1100.00%


static inline void xgene_pmu_stop_counters(struct xgene_pmu_dev *pmu_dev) { u32 val; val = readl(pmu_dev->inf->csr + PMU_PMCR); val &= ~PMU_PMCR_E; writel(val, pmu_dev->inf->csr + PMU_PMCR); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen46100.00%1100.00%
Total46100.00%1100.00%


static void xgene_perf_pmu_enable(struct pmu *pmu) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu); int enabled = bitmap_weight(pmu_dev->cntr_assign_mask, pmu_dev->max_counters); if (!enabled) return; xgene_pmu_start_counters(pmu_dev); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen46100.00%1100.00%
Total46100.00%1100.00%


static void xgene_perf_pmu_disable(struct pmu *pmu) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu); xgene_pmu_stop_counters(pmu_dev); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen26100.00%1100.00%
Total26100.00%1100.00%


static int xgene_perf_event_init(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); struct hw_perf_event *hw = &event->hw; struct perf_event *sibling; /* Test the event attr type check for PMU enumeration */ if (event->attr.type != event->pmu->type) return -ENOENT; /* * SOC PMU counters are shared across all cores. * Therefore, it does not support per-process mode. * Also, it does not support event sampling mode. */ if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) return -EINVAL; /* SOC counters do not have usr/os/guest/host bits */ if (event->attr.exclude_user || event->attr.exclude_kernel || event->attr.exclude_host || event->attr.exclude_guest) return -EINVAL; if (event->cpu < 0) return -EINVAL; /* * Many perf core operations (eg. events rotation) operate on a * single CPU context. This is obvious for CPU PMUs, where one * expects the same sets of events being observed on all CPUs, * but can lead to issues for off-core PMUs, where each * event could be theoretically assigned to a different CPU. To * mitigate this, we enforce CPU assignment to one, selected * processor (the one described in the "cpumask" attribute). */ event->cpu = cpumask_first(&pmu_dev->parent->cpu); hw->config = event->attr.config; /* * Each bit of the config1 field represents an agent from which the * request of the event come. The event is counted only if it's caused * by a request of an agent has the bit cleared. * By default, the event is counted for all agents. */ hw->config_base = event->attr.config1; /* * We must NOT create groups containing mixed PMUs, although software * events are acceptable */ if (event->group_leader->pmu != event->pmu && !is_software_event(event->group_leader)) return -EINVAL; list_for_each_entry(sibling, &event->group_leader->sibling_list, group_entry) if (sibling->pmu != event->pmu && !is_software_event(sibling)) return -EINVAL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen210100.00%1100.00%
Total210100.00%1100.00%


static void xgene_perf_enable_event(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); xgene_pmu_write_evttype(pmu_dev, GET_CNTR(event), GET_EVENTID(event)); xgene_pmu_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_enable_counter(pmu_dev, GET_CNTR(event)); xgene_pmu_enable_counter_int(pmu_dev, GET_CNTR(event)); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen100100.00%1100.00%
Total100100.00%1100.00%


static void xgene_perf_disable_event(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); xgene_pmu_disable_counter(pmu_dev, GET_CNTR(event)); xgene_pmu_disable_counter_int(pmu_dev, GET_CNTR(event)); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen43100.00%1100.00%
Total43100.00%1100.00%


static void xgene_perf_event_set_period(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); struct hw_perf_event *hw = &event->hw; /* * The X-Gene PMU counters have a period of 2^32. To account for the * possiblity of extreme interrupt latency we program for a period of * half that. Hopefully we can handle the interrupt before another 2^31 * events occur and the counter overtakes its previous value. */ u64 val = 1ULL << 31; local64_set(&hw->prev_count, val); xgene_pmu_write_counter(pmu_dev, hw->idx, (u32) val); }

Contributors

PersonTokensPropCommitsCommitProp
Tai Nguyen65100.00%1100.00%
Total65100.00%1100.00%


static void xgene_perf_event_update(struct perf_event *event) { struct xgene_pmu_dev *pmu_dev = to_pmu_dev(event->pmu); struct hw_perf_event *hw = &event->hw; u64 delta, prev_raw_count, new_raw_count; again: prev_raw_count = local64_read(&