drivers/perf/arm-cci.c

Source file repositories/reference/linux-study-clean/drivers/perf/arm-cci.c

File Facts

System
Linux kernel
Corpus path
drivers/perf/arm-cci.c
Extension
.c
Size
48588 bytes
Lines
1714
Domain
Driver Families
Bucket
drivers/perf
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct event_range {
	u32 min;
	u32 max;
};

struct cci_pmu_hw_events {
	struct perf_event **events;
	unsigned long *used_mask;
	raw_spinlock_t pmu_lock;
};

struct cci_pmu;
/*
 * struct cci_pmu_model:
 * @fixed_hw_cntrs - Number of fixed event counters
 * @num_hw_cntrs - Maximum number of programmable event counters
 * @cntr_size - Size of an event counter mapping
 */
struct cci_pmu_model {
	char *name;
	u32 fixed_hw_cntrs;
	u32 num_hw_cntrs;
	u32 cntr_size;
	struct attribute **format_attrs;
	struct attribute **event_attrs;
	struct event_range event_ranges[CCI_IF_MAX];
	int (*validate_hw_event)(struct cci_pmu *, unsigned long);
	int (*get_event_idx)(struct cci_pmu *, struct cci_pmu_hw_events *, unsigned long);
	void (*write_counters)(struct cci_pmu *, unsigned long *);
};

static struct cci_pmu_model cci_pmu_models[];

struct cci_pmu {
	void __iomem *base;
	void __iomem *ctrl_base;
	struct pmu pmu;
	int cpu;
	int nr_irqs;
	int *irqs;
	unsigned long active_irqs;
	const struct cci_pmu_model *model;
	struct cci_pmu_hw_events hw_events;
	struct platform_device *plat_device;
	int num_cntrs;
	atomic_t active_events;
	struct mutex reserve_mutex;
};

#define to_cci_pmu(c)	(container_of(c, struct cci_pmu, pmu))

static struct cci_pmu *g_cci_pmu;

enum cci_models {
#ifdef CONFIG_ARM_CCI400_PMU
	CCI400_R0,
	CCI400_R1,
#endif
#ifdef CONFIG_ARM_CCI5xx_PMU
	CCI500_R0,
	CCI550_R0,
#endif
	CCI_MODEL_MAX
};

static void pmu_write_counters(struct cci_pmu *cci_pmu,
				 unsigned long *mask);
static ssize_t __maybe_unused cci_pmu_event_show(struct device *dev,
			struct device_attribute *attr, char *buf);

#define CCI_EXT_ATTR_ENTRY(_name, _func, _config) 				\
	&((struct dev_ext_attribute[]) {					\
		{ __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config }	\
	})[0].attr.attr

#define CCI_FORMAT_EXT_ATTR_ENTRY(_name, _config) \
	CCI_EXT_ATTR_ENTRY(_name, device_show_string, _config)
#define CCI_EVENT_EXT_ATTR_ENTRY(_name, _config) \
	CCI_EXT_ATTR_ENTRY(_name, cci_pmu_event_show, (unsigned long)_config)

/* CCI400 PMU Specific definitions */

#ifdef CONFIG_ARM_CCI400_PMU

/* Port ids */
#define CCI400_PORT_S0		0
#define CCI400_PORT_S1		1
#define CCI400_PORT_S2		2
#define CCI400_PORT_S3		3
#define CCI400_PORT_S4		4

Annotation

Implementation Notes