/**
 * _register_dpll - low level registration of a DPLL clock
 * @hw: hardware clock definition for the clock
 * @node: device node for the clock
 *
 * Finalizes DPLL registration process. In case a failure (clk-ref or
 * clk-bypass is missing), the clock is added to retry list and
 * the initialization is retried on later stage.
 */
static void __init _register_dpll(struct clk_hw *hw,
                                  struct device_node *node)
{
    struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
    struct dpll_data *dd = clk_hw->dpll_data;
    struct clk *clk;

    clk = of_clk_get(node, 0);
    if (IS_ERR(clk)) {
        pr_debug("clk-ref missing for %s, retry later\n",
                 node->name);
        if (!ti_clk_retry_init(node, hw, _register_dpll))
            return;

        goto cleanup;
    }

    dd->clk_ref = __clk_get_hw(clk);

    clk = of_clk_get(node, 1);

    if (IS_ERR(clk)) {
        pr_debug("clk-bypass missing for %s, retry later\n",
                 node->name);
        if (!ti_clk_retry_init(node, hw, _register_dpll))
            return;

        goto cleanup;
    }

    dd->clk_bypass = __clk_get_hw(clk);

    /* register the clock */
    clk = clk_register(NULL, &clk_hw->hw);

    if (!IS_ERR(clk)) {
        omap2_init_clk_hw_omap_clocks(&clk_hw->hw);
        of_clk_add_provider(node, of_clk_src_simple_get, clk);
        kfree(clk_hw->hw.init->parent_names);
        kfree(clk_hw->hw.init);
        return;
    }

cleanup:
    kfree(clk_hw->dpll_data);
    kfree(clk_hw->hw.init->parent_names);
    kfree(clk_hw->hw.init);
    kfree(clk_hw);
}
Beispiel #2
0
static void __init omap_clk_register_apll(struct clk_hw *hw,
					  struct device_node *node)
{
	struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
	struct dpll_data *ad = clk_hw->dpll_data;
	struct clk *clk;

	ad->clk_ref = of_clk_get(node, 0);
	ad->clk_bypass = of_clk_get(node, 1);

	if (IS_ERR(ad->clk_ref) || IS_ERR(ad->clk_bypass)) {
		pr_debug("clk-ref or clk-bypass for %s not ready, retry\n",
			 node->name);
		if (!ti_clk_retry_init(node, hw, omap_clk_register_apll))
			return;

		goto cleanup;
	}

	clk = clk_register(NULL, &clk_hw->hw);
	if (!IS_ERR(clk)) {
		of_clk_add_provider(node, of_clk_src_simple_get, clk);
		kfree(clk_hw->hw.init->parent_names);
		kfree(clk_hw->hw.init);
		return;
	}

cleanup:
	kfree(clk_hw->dpll_data);
	kfree(clk_hw->hw.init->parent_names);
	kfree(clk_hw->hw.init);
	kfree(clk_hw);
}