err = clk_enable(ddata->clk); if (err) {
dev_err(&rproc->dev, "Failed to enable clock\n"); return err;
}
if (ddata->config->sw_reset) {
err = reset_control_deassert(ddata->sw_reset); if (err) {
dev_err(&rproc->dev, "Failed to deassert S/W Reset\n"); goto sw_reset_fail;
}
}
if (ddata->config->pwr_reset) {
err = reset_control_deassert(ddata->pwr_reset); if (err) {
dev_err(&rproc->dev, "Failed to deassert Power Reset\n"); goto pwr_reset_fail;
}
}
dev_info(&rproc->dev, "Started from 0x%llx\n", rproc->bootaddr);
return 0;
pwr_reset_fail: if (ddata->config->pwr_reset)
reset_control_assert(ddata->sw_reset);
sw_reset_fail:
clk_disable(ddata->clk);
if (ddata->config->sw_reset) {
sw_err = reset_control_assert(ddata->sw_reset); if (sw_err)
dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
}
if (ddata->config->pwr_reset) {
pwr_err = reset_control_assert(ddata->pwr_reset); if (pwr_err)
dev_err(&rproc->dev, "Failed to assert Power Reset\n");
}
if (ddata->config->sw_reset) {
ddata->sw_reset = devm_reset_control_get_exclusive(dev, "sw_reset"); if (IS_ERR(ddata->sw_reset)) return dev_err_probe(dev, PTR_ERR(ddata->sw_reset), "Failed to get S/W Reset\n");
}
if (ddata->config->pwr_reset) {
ddata->pwr_reset = devm_reset_control_get_exclusive(dev, "pwr_reset"); if (IS_ERR(ddata->pwr_reset)) return dev_err_probe(dev, PTR_ERR(ddata->pwr_reset), "Failed to get Power Reset\n");
}
ddata->clk = devm_clk_get(dev, NULL); if (IS_ERR(ddata->clk)) return dev_err_probe(dev, PTR_ERR(ddata->clk), "Failed to get clock\n");
err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate); if (err) {
dev_err(dev, "failed to get clock frequency\n"); return err;
}
ddata->boot_base = syscon_regmap_lookup_by_phandle_args(np, "st,syscfg",
1, &ddata->boot_offset); if (IS_ERR(ddata->boot_base)) return dev_err_probe(dev, PTR_ERR(ddata->boot_base), "Boot base not found\n");
err = clk_prepare(ddata->clk); if (err)
dev_err(dev, "failed to get clock\n");
/* * To control a co-processor without IPC mechanism. * This driver can be used without mbox and rpmsg.
*/
chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_rx"); if (IS_ERR(chan)) {
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan), "failed to request mbox chan 0\n"); goto free_clk;
}
ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_RX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_tx"); if (IS_ERR(chan)) {
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan), "failed to request mbox chan 0\n"); goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_TX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_rx"); if (IS_ERR(chan)) {
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan), "failed to request mbox chan 1\n"); goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_RX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_tx"); if (IS_ERR(chan)) {
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan), "failed to request mbox chan 1\n"); goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_TX] = chan;
}
ret = rproc_add(rproc); if (ret) goto free_mbox;
return 0;
free_mbox: for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
mbox_free_channel(ddata->mbox_chan[i]);
free_clk:
clk_unprepare(ddata->clk);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.