in mtk_scp.c [749:858]
static int scp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct mtk_scp *scp;
struct rproc *rproc;
struct resource *res;
char *fw_name = "scp.img";
int ret, i;
rproc = rproc_alloc(dev,
np->name,
&scp_ops,
fw_name,
sizeof(*scp));
if (!rproc) {
dev_err(dev, "unable to allocate remoteproc\n");
return -ENOMEM;
}
scp = (struct mtk_scp *)rproc->priv;
scp->rproc = rproc;
scp->dev = dev;
scp->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, scp);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
scp->sram_base = devm_ioremap_resource(dev, res);
if (IS_ERR((__force void *)scp->sram_base)) {
dev_err(dev, "Failed to parse and map sram memory\n");
ret = PTR_ERR((__force void *)scp->sram_base);
goto free_rproc;
}
scp->sram_size = resource_size(res);
scp->sram_phys = res->start;
/* l1tcm is an optional memory region */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm");
scp->l1tcm_base = devm_ioremap_resource(dev, res);
if (IS_ERR((__force void *)scp->l1tcm_base)) {
ret = PTR_ERR((__force void *)scp->l1tcm_base);
if (ret != -EINVAL) {
dev_err(dev, "Failed to map l1tcm memory\n");
goto free_rproc;
}
} else {
scp->l1tcm_size = resource_size(res);
scp->l1tcm_phys = res->start;
}
mutex_init(&scp->send_lock);
for (i = 0; i < SCP_IPI_MAX; i++)
mutex_init(&scp->ipi_desc[i].lock);
scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
if (IS_ERR((__force void *)scp->reg_base)) {
dev_err(dev, "Failed to parse and map cfg memory\n");
ret = PTR_ERR((__force void *)scp->reg_base);
goto destroy_mutex;
}
ret = scp_map_memory_region(scp);
if (ret)
goto destroy_mutex;
ret = scp->data->scp_clk_get(scp);
if (ret)
goto release_dev_mem;
/* register SCP initialization IPI */
ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
if (ret) {
dev_err(dev, "Failed to register IPI_SCP_INIT\n");
goto release_dev_mem;
}
init_waitqueue_head(&scp->run.wq);
init_waitqueue_head(&scp->ack_wq);
scp_add_rpmsg_subdev(scp);
ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), NULL,
scp_irq_handler, IRQF_ONESHOT,
pdev->name, scp);
if (ret) {
dev_err(dev, "failed to request irq\n");
goto remove_subdev;
}
ret = rproc_add(rproc);
if (ret)
goto remove_subdev;
return 0;
remove_subdev:
scp_remove_rpmsg_subdev(scp);
scp_ipi_unregister(scp, SCP_IPI_INIT);
release_dev_mem:
scp_unmap_memory_region(scp);
destroy_mutex:
for (i = 0; i < SCP_IPI_MAX; i++)
mutex_destroy(&scp->ipi_desc[i].lock);
mutex_destroy(&scp->send_lock);
free_rproc:
rproc_free(rproc);
return ret;
}