Add support for the PMU counters on Cavium SOC memory controllers.
This patch also adds generic functions to allow supporting more
devices with PMU counters.
Properties of the LMC PMU counters:
- not stoppable
- fixed purpose
- read-only
- one PCI device per memory controller
Signed-off-by: Jan Glauber <jglauber@xxxxxxxxxx>
---
drivers/perf/Kconfig | 8 +
drivers/perf/Makefile | 1 +
drivers/perf/cavium_pmu.c | 430 ++++++++++++++++++++++++++++++++++++++++
drivers/soc/cavium/cavium_lmc.c | 4 +
include/linux/cpuhotplug.h | 1 +
include/linux/soc/cavium/lmc.h | 3 +
6 files changed, 447 insertions(+)
create mode 100644 drivers/perf/cavium_pmu.c
+int cvm_lmc_pmu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct cvm_pmu_dev *next, *lmc;
+ int nr = 0, ret = -ENOMEM;
+ char *name;
+
+ lmc = devm_kzalloc(&pdev->dev, sizeof(*lmc), GFP_KERNEL);
+ if (!lmc)
+ return -ENOMEM;
+
+ lmc->map = devm_ioremap(&pdev->dev, pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (!lmc->map)
+ return -EINVAL;
+
+ list_for_each_entry(next, &cvm_pmu_lmcs, entry)
+ nr++;
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "lmc%d", nr);
+ if (!name)
+ return -ENOMEM;
+
+ lmc->pdev = pdev;
+ lmc->num_counters = ARRAY_SIZE(cvm_pmu_lmc_events_attr) - 1;
+ lmc->pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+ .name = name,
+ .event_init = cvm_pmu_event_init,
+ .add = cvm_pmu_lmc_add,
+ .del = cvm_pmu_del,
+ .start = cvm_pmu_start,
+ .stop = cvm_pmu_stop,
+ .read = cvm_pmu_read,
+ .attr_groups = cvm_pmu_lmc_attr_groups,
+ };
+