drivers/perf/fsl_imx9_ddr_perf.c

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

File Facts

System
Linux kernel
Corpus path
drivers/perf/fsl_imx9_ddr_perf.c
Extension
.c
Size
25624 bytes
Lines
888
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 imx_ddr_devtype_data {
	const char *identifier;		/* system PMU identifier for userspace */
	unsigned int filter_ver;	/* AXI filter version */
};

struct ddr_pmu {
	struct pmu pmu;
	void __iomem *base;
	unsigned int cpu;
	struct hlist_node node;
	struct device *dev;
	struct perf_event *events[NUM_COUNTERS];
	int active_events;
	enum cpuhp_state cpuhp_state;
	const struct imx_ddr_devtype_data *devtype_data;
	int irq;
	int id;
};

static const struct imx_ddr_devtype_data imx91_devtype_data = {
	.identifier = "imx91",
	.filter_ver = DDR_PERF_AXI_FILTER_V1
};

static const struct imx_ddr_devtype_data imx93_devtype_data = {
	.identifier = "imx93",
	.filter_ver = DDR_PERF_AXI_FILTER_V1
};

static const struct imx_ddr_devtype_data imx94_devtype_data = {
	.identifier = "imx94",
	.filter_ver = DDR_PERF_AXI_FILTER_V2
};

static const struct imx_ddr_devtype_data imx95_devtype_data = {
	.identifier = "imx95",
	.filter_ver = DDR_PERF_AXI_FILTER_V2
};

static inline bool axi_filter_v1(struct ddr_pmu *pmu)
{
	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V1;
}

static inline bool axi_filter_v2(struct ddr_pmu *pmu)
{
	return pmu->devtype_data->filter_ver == DDR_PERF_AXI_FILTER_V2;
}

static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
	{ .compatible = "fsl,imx91-ddr-pmu", .data = &imx91_devtype_data },
	{ .compatible = "fsl,imx93-ddr-pmu", .data = &imx93_devtype_data },
	{ .compatible = "fsl,imx94-ddr-pmu", .data = &imx94_devtype_data },
	{ .compatible = "fsl,imx95-ddr-pmu", .data = &imx95_devtype_data },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_ddr_pmu_dt_ids);

static ssize_t ddr_perf_identifier_show(struct device *dev,
					struct device_attribute *attr,
					char *page)
{
	struct ddr_pmu *pmu = dev_get_drvdata(dev);

	return sysfs_emit(page, "%s\n", pmu->devtype_data->identifier);
}

static struct device_attribute ddr_perf_identifier_attr =
	__ATTR(identifier, 0444, ddr_perf_identifier_show, NULL);

static struct attribute *ddr_perf_identifier_attrs[] = {
	&ddr_perf_identifier_attr.attr,
	NULL,
};

static struct attribute_group ddr_perf_identifier_attr_group = {
	.attrs = ddr_perf_identifier_attrs,
};

static ssize_t ddr_perf_cpumask_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct ddr_pmu *pmu = dev_get_drvdata(dev);

	return cpumap_print_to_pagebuf(true, buf, cpumask_of(pmu->cpu));
}

static struct device_attribute ddr_perf_cpumask_attr =
	__ATTR(cpumask, 0444, ddr_perf_cpumask_show, NULL);

Annotation

Implementation Notes