static int imx_dsp_rproc_probe()

in imx_dsp_rproc.c [956:1026]


static int imx_dsp_rproc_probe(struct platform_device *pdev)
{
	const struct imx_dsp_rproc_dcfg *dsp_dcfg;
	struct device *dev = &pdev->dev;
	struct imx_dsp_rproc *priv;
	struct rproc *rproc;
	const char *fw_name;
	int ret;

	dsp_dcfg = of_device_get_match_data(dev);
	if (!dsp_dcfg)
		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, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
			    sizeof(*priv));
	if (!rproc)
		return -ENOMEM;

	priv = rproc->priv;
	priv->rproc = rproc;
	priv->dsp_dcfg = dsp_dcfg;

	dev_set_drvdata(dev, rproc);

	INIT_WORK(&priv->rproc_work, imx_dsp_rproc_vq_work);

	ret = imx_dsp_rproc_detect_mode(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
		goto err_put_rproc;
	}

	/* There are multiple power domains required by DSP on some platform */
	ret = imx_dsp_attach_pm_domains(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
		goto err_put_rproc;
	}
	/* Get clocks */
	ret = imx_dsp_rproc_clk_get(priv);
	if (ret) {
		dev_err(dev, "failed on imx_dsp_rproc_clk_get\n");
		goto err_detach_domains;
	}

	init_completion(&priv->pm_comp);
	rproc->auto_boot = false;
	ret = rproc_add(rproc);
	if (ret) {
		dev_err(dev, "rproc_add failed\n");
		goto err_detach_domains;
	}

	pm_runtime_enable(dev);

	return 0;

err_detach_domains:
	imx_dsp_detach_pm_domains(priv);
err_put_rproc:
	rproc_free(rproc);

	return ret;
}