in ti_k3_dsp_remoteproc.c [587:715]
static int k3_dsp_rproc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const struct k3_dsp_dev_data *data;
struct k3_dsp_rproc *kproc;
struct rproc *rproc;
const char *fw_name;
int ret = 0;
int ret1;
data = of_device_get_match_data(dev);
if (!data)
return -ENODEV;
ret = rproc_of_parse_firmware(dev, 0, &fw_name);
if (ret) {
dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
ret);
return ret;
}
rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops, fw_name,
sizeof(*kproc));
if (!rproc)
return -ENOMEM;
rproc->has_iommu = false;
rproc->recovery_disabled = true;
if (data->uses_lreset) {
rproc->ops->prepare = k3_dsp_rproc_prepare;
rproc->ops->unprepare = k3_dsp_rproc_unprepare;
}
kproc = rproc->priv;
kproc->rproc = rproc;
kproc->dev = dev;
kproc->data = data;
kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
if (IS_ERR(kproc->ti_sci)) {
ret = PTR_ERR(kproc->ti_sci);
if (ret != -EPROBE_DEFER) {
dev_err(dev, "failed to get ti-sci handle, ret = %d\n",
ret);
}
kproc->ti_sci = NULL;
goto free_rproc;
}
ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);
if (ret) {
dev_err(dev, "missing 'ti,sci-dev-id' property\n");
goto put_sci;
}
kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(kproc->reset)) {
ret = PTR_ERR(kproc->reset);
dev_err(dev, "failed to get reset, status = %d\n", ret);
goto put_sci;
}
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
if (IS_ERR(kproc->tsp)) {
dev_err(dev, "failed to construct ti-sci proc control, ret = %d\n",
ret);
ret = PTR_ERR(kproc->tsp);
goto put_sci;
}
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
dev_err(dev, "ti_sci_proc_request failed, ret = %d\n", ret);
goto free_tsp;
}
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret)
goto release_tsp;
ret = k3_dsp_reserved_mem_init(kproc);
if (ret) {
dev_err(dev, "reserved memory init failed, ret = %d\n", ret);
goto release_tsp;
}
/*
* ensure the DSP local reset is asserted to ensure the DSP doesn't
* execute bogus code in .prepare() when the module reset is released.
*/
if (data->uses_lreset) {
ret = reset_control_status(kproc->reset);
if (ret < 0) {
dev_err(dev, "failed to get reset status, status = %d\n",
ret);
goto release_mem;
} else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for device\n");
k3_dsp_rproc_reset(kproc);
}
}
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",
ret);
goto release_mem;
}
platform_set_drvdata(pdev, kproc);
return 0;
release_mem:
k3_dsp_reserved_mem_exit(kproc);
release_tsp:
ret1 = ti_sci_proc_release(kproc->tsp);
if (ret1)
dev_err(dev, "failed to release proc, ret = %d\n", ret1);
free_tsp:
kfree(kproc->tsp);
put_sci:
ret1 = ti_sci_put_handle(kproc->ti_sci);
if (ret1)
dev_err(dev, "failed to put ti_sci handle, ret = %d\n", ret1);
free_rproc:
rproc_free(rproc);
return ret;
}