composite = to_clk_composite(hw); if (composite->mux_hw)
mux = to_clk_mux(composite->mux_hw); if (composite->gate_hw)
gate = to_clk_gate(composite->gate_hw); if (composite->rate_hw)
div = to_clk_divider(composite->rate_hw);
mcd = device_get_match_data(&pdev->dev); if (!mcd) { /* Clock driver wasn't registered from devicetree */
id = platform_get_device_id(pdev); if (id)
mcd = (conststruct mtk_clk_desc *)id->driver_data;
if (!mcd) return -EINVAL;
}
/* Composite and divider clocks needs us to pass iomem pointer */ if (mcd->composite_clks || mcd->divider_clks) { if (!mcd->shared_io)
base = devm_platform_ioremap_resource(pdev, 0); else
base = of_iomap(node, 0);
if (IS_ERR_OR_NULL(base)) return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
}
if (mcd->need_runtime_pm) {
devm_pm_runtime_enable(&pdev->dev); /* * Do a pm_runtime_resume_and_get() to workaround a possible * deadlock between clk_register() and the genpd framework.
*/
r = pm_runtime_resume_and_get(&pdev->dev); if (r) return r;
}
/* Calculate how many clk_hw_onecell_data entries to allocate */
num_clks = mcd->num_clks + mcd->num_composite_clks;
num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
num_clks += mcd->num_mux_clks + mcd->num_divider_clks;
clk_data = mtk_alloc_clk_data(num_clks); if (!clk_data) {
r = -ENOMEM; goto free_base;
}
if (mcd->fixed_clks) {
r = mtk_clk_register_fixed_clks(mcd->fixed_clks,
mcd->num_fixed_clks, clk_data); if (r) goto free_data;
}
if (mcd->factor_clks) {
r = mtk_clk_register_factors(mcd->factor_clks,
mcd->num_factor_clks, clk_data); if (r) goto unregister_fixed_clks;
}
if (mcd->mux_clks) {
r = mtk_clk_register_muxes(&pdev->dev, mcd->mux_clks,
mcd->num_mux_clks, node,
mcd->clk_lock, clk_data); if (r) goto unregister_factors;
}
if (mcd->composite_clks) { /* We don't check composite_lock because it's optional */
r = mtk_clk_register_composites(&pdev->dev,
mcd->composite_clks,
mcd->num_composite_clks,
base, mcd->clk_lock, clk_data); if (r) goto unregister_muxes;
}
if (mcd->divider_clks) {
r = mtk_clk_register_dividers(&pdev->dev,
mcd->divider_clks,
mcd->num_divider_clks,
base, mcd->clk_lock, clk_data); if (r) goto unregister_composites;
}
if (mcd->clks) {
r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks,
mcd->num_clks, clk_data); if (r) goto unregister_dividers;
}
if (mcd->clk_notifier_func) { struct clk *mfg_mux = clk_data->hws[mcd->mfg_clk_idx]->clk;
r = mcd->clk_notifier_func(&pdev->dev, mfg_mux); if (r) goto unregister_clks;
}
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (r) goto unregister_clks;
platform_set_drvdata(pdev, clk_data);
if (mcd->rst_desc) {
r = mtk_register_reset_controller_with_dev(&pdev->dev,
mcd->rst_desc); if (r) goto unregister_clks;
}
if (mcd->need_runtime_pm)
pm_runtime_put(&pdev->dev);
return r;
unregister_clks: if (mcd->clks)
mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
unregister_dividers: if (mcd->divider_clks)
mtk_clk_unregister_dividers(mcd->divider_clks,
mcd->num_divider_clks, clk_data);
unregister_composites: if (mcd->composite_clks)
mtk_clk_unregister_composites(mcd->composite_clks,
mcd->num_composite_clks, clk_data);
unregister_muxes: if (mcd->mux_clks)
mtk_clk_unregister_muxes(mcd->mux_clks,
mcd->num_mux_clks, clk_data);
unregister_factors: if (mcd->factor_clks)
mtk_clk_unregister_factors(mcd->factor_clks,
mcd->num_factor_clks, clk_data);
unregister_fixed_clks: if (mcd->fixed_clks)
mtk_clk_unregister_fixed_clks(mcd->fixed_clks,
mcd->num_fixed_clks, clk_data);
free_data:
mtk_free_clk_data(clk_data);
free_base: if (mcd->shared_io && base)
iounmap(base);
if (mcd->need_runtime_pm)
pm_runtime_put(&pdev->dev); return r;
}
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.