in qcom_q6v5_adsp.c [427:497]
static int adsp_probe(struct platform_device *pdev)
{
const struct adsp_pil_data *desc;
struct qcom_adsp *adsp;
struct rproc *rproc;
int ret;
desc = of_device_get_match_data(&pdev->dev);
if (!desc)
return -EINVAL;
rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
desc->firmware_name, sizeof(*adsp));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
}
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
adsp = (struct qcom_adsp *)rproc->priv;
adsp->dev = &pdev->dev;
adsp->rproc = rproc;
adsp->info_name = desc->sysmon_name;
platform_set_drvdata(pdev, adsp);
ret = adsp_alloc_memory_region(adsp);
if (ret)
goto free_rproc;
ret = adsp_init_clock(adsp, desc->clk_ids);
if (ret)
goto free_rproc;
pm_runtime_enable(adsp->dev);
ret = adsp_init_reset(adsp);
if (ret)
goto disable_pm;
ret = adsp_init_mmio(adsp, pdev);
if (ret)
goto disable_pm;
ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, NULL,
qcom_adsp_pil_handover);
if (ret)
goto disable_pm;
qcom_add_glink_subdev(rproc, &adsp->glink_subdev, desc->ssr_name);
qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
adsp->sysmon = qcom_add_sysmon_subdev(rproc,
desc->sysmon_name,
desc->ssctl_id);
if (IS_ERR(adsp->sysmon)) {
ret = PTR_ERR(adsp->sysmon);
goto disable_pm;
}
ret = rproc_add(rproc);
if (ret)
goto disable_pm;
return 0;
disable_pm:
pm_runtime_disable(adsp->dev);
free_rproc:
rproc_free(rproc);
return ret;
}