in tegra/bpmp.c [688:795]
static int tegra_bpmp_probe(struct platform_device *pdev)
{
struct tegra_bpmp *bpmp;
char tag[TAG_SZ];
size_t size;
int err;
bpmp = devm_kzalloc(&pdev->dev, sizeof(*bpmp), GFP_KERNEL);
if (!bpmp)
return -ENOMEM;
bpmp->soc = of_device_get_match_data(&pdev->dev);
bpmp->dev = &pdev->dev;
INIT_LIST_HEAD(&bpmp->mrqs);
spin_lock_init(&bpmp->lock);
bpmp->threaded.count = bpmp->soc->channels.thread.count;
sema_init(&bpmp->threaded.lock, bpmp->threaded.count);
size = BITS_TO_LONGS(bpmp->threaded.count) * sizeof(long);
bpmp->threaded.allocated = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!bpmp->threaded.allocated)
return -ENOMEM;
bpmp->threaded.busy = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!bpmp->threaded.busy)
return -ENOMEM;
spin_lock_init(&bpmp->atomic_tx_lock);
bpmp->tx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->tx_channel),
GFP_KERNEL);
if (!bpmp->tx_channel)
return -ENOMEM;
bpmp->rx_channel = devm_kzalloc(&pdev->dev, sizeof(*bpmp->rx_channel),
GFP_KERNEL);
if (!bpmp->rx_channel)
return -ENOMEM;
bpmp->threaded_channels = devm_kcalloc(&pdev->dev, bpmp->threaded.count,
sizeof(*bpmp->threaded_channels),
GFP_KERNEL);
if (!bpmp->threaded_channels)
return -ENOMEM;
err = bpmp->soc->ops->init(bpmp);
if (err < 0)
return err;
err = tegra_bpmp_request_mrq(bpmp, MRQ_PING,
tegra_bpmp_mrq_handle_ping, bpmp);
if (err < 0)
goto deinit;
err = tegra_bpmp_ping(bpmp);
if (err < 0) {
dev_err(&pdev->dev, "failed to ping BPMP: %d\n", err);
goto free_mrq;
}
err = tegra_bpmp_get_firmware_tag(bpmp, tag, sizeof(tag));
if (err < 0) {
dev_err(&pdev->dev, "failed to get firmware tag: %d\n", err);
goto free_mrq;
}
dev_info(&pdev->dev, "firmware: %.*s\n", (int)sizeof(tag), tag);
platform_set_drvdata(pdev, bpmp);
err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev);
if (err < 0)
goto free_mrq;
if (of_find_property(pdev->dev.of_node, "#clock-cells", NULL)) {
err = tegra_bpmp_init_clocks(bpmp);
if (err < 0)
goto free_mrq;
}
if (of_find_property(pdev->dev.of_node, "#reset-cells", NULL)) {
err = tegra_bpmp_init_resets(bpmp);
if (err < 0)
goto free_mrq;
}
if (of_find_property(pdev->dev.of_node, "#power-domain-cells", NULL)) {
err = tegra_bpmp_init_powergates(bpmp);
if (err < 0)
goto free_mrq;
}
err = tegra_bpmp_init_debugfs(bpmp);
if (err < 0)
dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err);
return 0;
free_mrq:
tegra_bpmp_free_mrq(bpmp, MRQ_PING, bpmp);
deinit:
if (bpmp->soc->ops->deinit)
bpmp->soc->ops->deinit(bpmp);
return err;
}