]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/clk/clk.c
Merge branches 'clk-remove-asm-clkdev', 'clk-debugfs-fixes', 'clk-renesas' and 'clk...
[linux.git] / drivers / clk / clk.c
index 0a52357ded5c16bfaf35a28f4aed1b797053d54c..32867dda6c1ca6824ff212abae308f9a81d395c6 100644 (file)
@@ -1747,6 +1747,9 @@ static void clk_change_rate(struct clk_core *core)
                best_parent_rate = core->parent->rate;
        }
 
+       if (clk_pm_runtime_get(core))
+               return;
+
        if (core->flags & CLK_SET_RATE_UNGATE) {
                unsigned long flags;
 
@@ -1817,6 +1820,8 @@ static void clk_change_rate(struct clk_core *core)
        /* handle the new child who might not be in core->children yet */
        if (core->new_child)
                clk_change_rate(core->new_child);
+
+       clk_pm_runtime_put(core);
 }
 
 static unsigned long clk_core_req_round_rate_nolock(struct clk_core *core,
@@ -2959,14 +2964,17 @@ static int __clk_core_init(struct clk_core *core)
         */
        hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
                struct clk_core *parent = __clk_init_parent(orphan);
+               unsigned long flags;
 
                /*
                 * we could call __clk_set_parent, but that would result in a
                 * redundant call to the .set_rate op, if it exists
                 */
                if (parent) {
-                       __clk_set_parent_before(orphan, parent);
-                       __clk_set_parent_after(orphan, parent, NULL);
+                       /* update the clk tree topology */
+                       flags = clk_enable_lock();
+                       clk_reparent(orphan, parent);
+                       clk_enable_unlock(flags);
                        __clk_recalc_accuracies(orphan);
                        __clk_recalc_rates(orphan, 0);
                }
@@ -3067,7 +3075,13 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
                ret = -ENOMEM;
                goto fail_name;
        }
+
+       if (WARN_ON(!hw->init->ops)) {
+               ret = -EINVAL;
+               goto fail_ops;
+       }
        core->ops = hw->init->ops;
+
        if (dev && pm_runtime_enabled(dev))
                core->dev = dev;
        if (dev && dev->driver)
@@ -3129,6 +3143,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
                kfree_const(core->parent_names[i]);
        kfree(core->parent_names);
 fail_parent_names:
+fail_ops:
        kfree_const(core->name);
 fail_name:
        kfree(core);