static int l2_cache_pmu_probe()

in qcom_l2_pmu.c [891:966]


static int l2_cache_pmu_probe(struct platform_device *pdev)
{
	int err;
	struct l2cache_pmu *l2cache_pmu;

	l2cache_pmu =
		devm_kzalloc(&pdev->dev, sizeof(*l2cache_pmu), GFP_KERNEL);
	if (!l2cache_pmu)
		return -ENOMEM;

	INIT_LIST_HEAD(&l2cache_pmu->clusters);

	platform_set_drvdata(pdev, l2cache_pmu);
	l2cache_pmu->pmu = (struct pmu) {
		/* suffix is instance id for future use with multiple sockets */
		.name		= "l2cache_0",
		.task_ctx_nr    = perf_invalid_context,
		.pmu_enable	= l2_cache_pmu_enable,
		.pmu_disable	= l2_cache_pmu_disable,
		.event_init	= l2_cache_event_init,
		.add		= l2_cache_event_add,
		.del		= l2_cache_event_del,
		.start		= l2_cache_event_start,
		.stop		= l2_cache_event_stop,
		.read		= l2_cache_event_read,
		.attr_groups	= l2_cache_pmu_attr_grps,
		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
	};

	l2cache_pmu->num_counters = get_num_counters();
	l2cache_pmu->pdev = pdev;
	l2cache_pmu->pmu_cluster = devm_alloc_percpu(&pdev->dev,
						     struct cluster_pmu *);
	if (!l2cache_pmu->pmu_cluster)
		return -ENOMEM;

	l2_cycle_ctr_idx = l2cache_pmu->num_counters - 1;
	l2_counter_present_mask = GENMASK(l2cache_pmu->num_counters - 2, 0) |
		BIT(L2CYCLE_CTR_BIT);

	cpumask_clear(&l2cache_pmu->cpumask);

	/* Read cluster info and initialize each cluster */
	err = device_for_each_child(&pdev->dev, l2cache_pmu,
				    l2_cache_pmu_probe_cluster);
	if (err)
		return err;

	if (l2cache_pmu->num_pmus == 0) {
		dev_err(&pdev->dev, "No hardware L2 cache PMUs found\n");
		return -ENODEV;
	}

	err = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
				       &l2cache_pmu->node);
	if (err) {
		dev_err(&pdev->dev, "Error %d registering hotplug", err);
		return err;
	}

	err = perf_pmu_register(&l2cache_pmu->pmu, l2cache_pmu->pmu.name, -1);
	if (err) {
		dev_err(&pdev->dev, "Error %d registering L2 cache PMU\n", err);
		goto out_unregister;
	}

	dev_info(&pdev->dev, "Registered L2 cache PMU using %d HW PMUs\n",
		 l2cache_pmu->num_pmus);

	return err;

out_unregister:
	cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
				    &l2cache_pmu->node);
	return err;
}