|
@@ -773,3 +773,74 @@ void propagate_rate(struct clk *tclk)
|
|
|
{
|
|
|
struct clk *clkp;
|
|
|
|
|
|
+ list_for_each_entry(clkp, &tclk->children, sibling) {
|
|
|
+ if (clkp->recalc)
|
|
|
+ clkp->rate = clkp->recalc(clkp);
|
|
|
+ propagate_rate(clkp);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static LIST_HEAD(root_clks);
|
|
|
+
|
|
|
+/**
|
|
|
+ * recalculate_root_clocks - recalculate and propagate all root clocks
|
|
|
+ *
|
|
|
+ * Recalculates all root clocks (clocks with no parent), which if the
|
|
|
+ * clock's .recalc is set correctly, should also propagate their rates.
|
|
|
+ * Called at init.
|
|
|
+ */
|
|
|
+void recalculate_root_clocks(void)
|
|
|
+{
|
|
|
+ struct clk *clkp;
|
|
|
+
|
|
|
+ list_for_each_entry(clkp, &root_clks, sibling) {
|
|
|
+ if (clkp->recalc)
|
|
|
+ clkp->rate = clkp->recalc(clkp);
|
|
|
+ propagate_rate(clkp);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * clk_preinit - initialize any fields in the struct clk before clk init
|
|
|
+ * @clk: struct clk * to initialize
|
|
|
+ *
|
|
|
+ * Initialize any struct clk fields needed before normal clk initialization
|
|
|
+ * can run. No return value.
|
|
|
+ */
|
|
|
+void clk_preinit(struct clk *clk)
|
|
|
+{
|
|
|
+ INIT_LIST_HEAD(&clk->children);
|
|
|
+}
|
|
|
+
|
|
|
+int clk_register(struct clk *clk)
|
|
|
+{
|
|
|
+ if (clk == NULL || IS_ERR(clk))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * trap out already registered clocks
|
|
|
+ */
|
|
|
+ if (clk->node.next || clk->node.prev)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ mutex_lock(&clocks_mutex);
|
|
|
+ if (clk->parent)
|
|
|
+ list_add(&clk->sibling, &clk->parent->children);
|
|
|
+ else
|
|
|
+ list_add(&clk->sibling, &root_clks);
|
|
|
+
|
|
|
+ list_add(&clk->node, &clocks);
|
|
|
+ if (clk->init)
|
|
|
+ clk->init(clk);
|
|
|
+ mutex_unlock(&clocks_mutex);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(clk_register);
|
|
|
+
|
|
|
+void clk_unregister(struct clk *clk)
|
|
|
+{
|
|
|
+ if (clk == NULL || IS_ERR(clk))
|
|
|
+ return;
|
|
|
+
|
|
|
+ mutex_lock(&clocks_mutex);
|