static int ddr_perf_probe()

in fsl_imx8_ddr_perf.c [679:771]


static int ddr_perf_probe(struct platform_device *pdev)
{
	struct ddr_pmu *pmu;
	struct device_node *np;
	void __iomem *base;
	char *name;
	int num;
	int ret;
	int irq;

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	np = pdev->dev.of_node;

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

	num = ddr_perf_init(pmu, base, &pdev->dev);

	platform_set_drvdata(pdev, pmu);

	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d",
			      num);
	if (!name) {
		ret = -ENOMEM;
		goto cpuhp_state_err;
	}

	pmu->devtype_data = of_device_get_match_data(&pdev->dev);

	pmu->cpu = raw_smp_processor_id();
	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
				      DDR_CPUHP_CB_NAME,
				      NULL,
				      ddr_perf_offline_cpu);

	if (ret < 0) {
		dev_err(&pdev->dev, "cpuhp_setup_state_multi failed\n");
		goto cpuhp_state_err;
	}

	pmu->cpuhp_state = ret;

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

	/* Request irq */
	irq = of_irq_get(np, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "Failed to get irq: %d", irq);
		ret = irq;
		goto ddr_perf_err;
	}

	ret = devm_request_irq(&pdev->dev, irq,
					ddr_perf_irq_handler,
					IRQF_NOBALANCING | IRQF_NO_THREAD,
					DDR_CPUHP_CB_NAME,
					pmu);
	if (ret < 0) {
		dev_err(&pdev->dev, "Request irq failed: %d", ret);
		goto ddr_perf_err;
	}

	pmu->irq = irq;
	ret = irq_set_affinity(pmu->irq, cpumask_of(pmu->cpu));
	if (ret) {
		dev_err(pmu->dev, "Failed to set interrupt affinity!\n");
		goto ddr_perf_err;
	}

	ret = perf_pmu_register(&pmu->pmu, name, -1);
	if (ret)
		goto ddr_perf_err;

	return 0;

ddr_perf_err:
	cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node);
cpuhp_instance_err:
	cpuhp_remove_multi_state(pmu->cpuhp_state);
cpuhp_state_err:
	ida_simple_remove(&ddr_ida, pmu->id);
	dev_warn(&pdev->dev, "i.MX8 DDR Perf PMU failed (%d), disabled\n", ret);
	return ret;
}