in qcom_q6v5_mss.c [1846:2006]
static int q6v5_probe(struct platform_device *pdev)
{
const struct rproc_hexagon_res *desc;
struct q6v5 *qproc;
struct rproc *rproc;
const char *mba_image;
int ret;
desc = of_device_get_match_data(&pdev->dev);
if (!desc)
return -EINVAL;
if (desc->need_mem_protection && !qcom_scm_is_available())
return -EPROBE_DEFER;
mba_image = desc->hexagon_mba_image;
ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
0, &mba_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mba firmware-name\n");
return ret;
}
rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
}
rproc->auto_boot = false;
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
qproc = (struct q6v5 *)rproc->priv;
qproc->dev = &pdev->dev;
qproc->rproc = rproc;
qproc->hexagon_mdt_image = "modem.mdt";
ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
goto free_rproc;
}
platform_set_drvdata(pdev, qproc);
qproc->has_qaccept_regs = desc->has_qaccept_regs;
qproc->has_ext_cntl_regs = desc->has_ext_cntl_regs;
qproc->has_vq6 = desc->has_vq6;
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
goto free_rproc;
ret = q6v5_alloc_memory_region(qproc);
if (ret)
goto free_rproc;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
goto free_rproc;
}
qproc->proxy_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc;
}
qproc->reset_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
desc->active_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n");
goto free_rproc;
}
qproc->active_clk_count = ret;
ret = q6v5_regulator_init(&pdev->dev, qproc->proxy_regs,
desc->proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
goto free_rproc;
}
qproc->proxy_reg_count = ret;
ret = q6v5_regulator_init(&pdev->dev, qproc->active_regs,
desc->active_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n");
goto free_rproc;
}
qproc->active_reg_count = ret;
ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds,
desc->proxy_pd_names);
/* Fallback to regulators for old device trees */
if (ret == -ENODATA && desc->fallback_proxy_supply) {
ret = q6v5_regulator_init(&pdev->dev,
qproc->fallback_proxy_regs,
desc->fallback_proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
goto free_rproc;
}
qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
goto free_rproc;
} else {
qproc->proxy_pd_count = ret;
}
qproc->has_alt_reset = desc->has_alt_reset;
ret = q6v5_init_reset(qproc);
if (ret)
goto detach_proxy_pds;
qproc->version = desc->version;
qproc->need_mem_protection = desc->need_mem_protection;
qproc->has_mba_logs = desc->has_mba_logs;
ret = qcom_q6v5_init(&qproc->q6v5, pdev, rproc, MPSS_CRASH_REASON_SMEM, "modem",
qcom_msa_handover);
if (ret)
goto detach_proxy_pds;
qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
qcom_add_glink_subdev(rproc, &qproc->glink_subdev, "mpss");
qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
if (IS_ERR(qproc->sysmon)) {
ret = PTR_ERR(qproc->sysmon);
goto remove_subdevs;
}
ret = rproc_add(rproc);
if (ret)
goto remove_sysmon_subdev;
return 0;
remove_sysmon_subdev:
qcom_remove_sysmon_subdev(qproc->sysmon);
remove_subdevs:
qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
free_rproc:
rproc_free(rproc);
return ret;
}