static int hisi_pa_pmu_probe()

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;
}