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