static int tad_pmu_probe()

in marvell_cn10k_tad_pmu.c [261:358]


static int tad_pmu_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct tad_region *regions;
	struct tad_pmu *tad_pmu;
	struct resource *res;
	u32 tad_pmu_page_size;
	u32 tad_page_size;
	u32 tad_cnt;
	int i, ret;
	char *name;

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

	platform_set_drvdata(pdev, tad_pmu);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Mem resource not found\n");
		return -ENODEV;
	}

	ret = of_property_read_u32(node, "marvell,tad-page-size",
				   &tad_page_size);
	if (ret) {
		dev_err(&pdev->dev, "Can't find tad-page-size property\n");
		return ret;
	}

	ret = of_property_read_u32(node, "marvell,tad-pmu-page-size",
				   &tad_pmu_page_size);
	if (ret) {
		dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n");
		return ret;
	}

	ret = of_property_read_u32(node, "marvell,tad-cnt", &tad_cnt);
	if (ret) {
		dev_err(&pdev->dev, "Can't find tad-cnt property\n");
		return ret;
	}

	regions = devm_kcalloc(&pdev->dev, tad_cnt,
			       sizeof(*regions), GFP_KERNEL);
	if (!regions)
		return -ENOMEM;

	/* ioremap the distributed TAD pmu regions */
	for (i = 0; i < tad_cnt && res->start < res->end; i++) {
		regions[i].base = devm_ioremap(&pdev->dev,
					       res->start,
					       tad_pmu_page_size);
		if (!regions[i].base) {
			dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
			return -ENOMEM;
		}
		res->start += tad_page_size;
	}

	tad_pmu->regions = regions;
	tad_pmu->region_cnt = tad_cnt;

	tad_pmu->pmu = (struct pmu) {

		.module		= THIS_MODULE,
		.attr_groups	= tad_pmu_attr_groups,
		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE |
				  PERF_PMU_CAP_NO_INTERRUPT,
		.task_ctx_nr	= perf_invalid_context,

		.event_init	= tad_pmu_event_init,
		.add		= tad_pmu_event_counter_add,
		.del		= tad_pmu_event_counter_del,
		.start		= tad_pmu_event_counter_start,
		.stop		= tad_pmu_event_counter_stop,
		.read		= tad_pmu_event_counter_read,
	};

	tad_pmu->cpu = raw_smp_processor_id();

	/* Register pmu instance for cpu hotplug */
	ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
					       &tad_pmu->node);
	if (ret) {
		dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
		return ret;
	}

	name = "tad";
	ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
	if (ret)
		cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
						    &tad_pmu->node);

	return ret;
}