in hisilicon/hisi_uncore_pa_pmu.c [389:444]
static int hisi_pa_pmu_probe(struct platform_device *pdev)
{
struct hisi_pmu *pa_pmu;
char *name;
int ret;
pa_pmu = devm_kzalloc(&pdev->dev, sizeof(*pa_pmu), GFP_KERNEL);
if (!pa_pmu)
return -ENOMEM;
ret = hisi_pa_pmu_dev_probe(pdev, pa_pmu);
if (ret)
return ret;
/*
* PA is attached in SICL and the CPU core is chosen to manage this
* PMU which is the nearest SCCL, while its SCCL_ID is greater than
* one with the SICL_ID.
*/
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%u_pa%u",
pa_pmu->sccl_id - 1, pa_pmu->index_id);
if (!name)
return -ENOMEM;
ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
&pa_pmu->node);
if (ret) {
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
return ret;
}
pa_pmu->pmu = (struct pmu) {
.module = THIS_MODULE,
.task_ctx_nr = perf_invalid_context,
.event_init = hisi_uncore_pmu_event_init,
.pmu_enable = hisi_uncore_pmu_enable,
.pmu_disable = hisi_uncore_pmu_disable,
.add = hisi_uncore_pmu_add,
.del = hisi_uncore_pmu_del,
.start = hisi_uncore_pmu_start,
.stop = hisi_uncore_pmu_stop,
.read = hisi_uncore_pmu_read,
.attr_groups = pa_pmu->pmu_events.attr_groups,
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
};
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
if (ret) {
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
&pa_pmu->node);
return ret;
}
platform_set_drvdata(pdev, pa_pmu);
return ret;
}