Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[linux-2.6.git] / drivers / sh / clk / core.c
index d6702e57d4285d150b2a94b6b94a6caf60652bc1..dc8d022c07a1505b2cc0bd86ccfb2e097c6f1f16 100644 (file)
@@ -34,6 +34,9 @@ static LIST_HEAD(clock_list);
 static DEFINE_SPINLOCK(clock_lock);
 static DEFINE_MUTEX(clock_list_sem);
 
+/* clock disable operations are not passed on to hardware during boot */
+static int allow_disable;
+
 void clk_rate_table_build(struct clk *clk,
                          struct cpufreq_frequency_table *freq_table,
                          int nr_freqs,
@@ -228,7 +231,7 @@ static void __clk_disable(struct clk *clk)
                return;
 
        if (!(--clk->usecount)) {
-               if (likely(clk->ops && clk->ops->disable))
+               if (likely(allow_disable && clk->ops && clk->ops->disable))
                        clk->ops->disable(clk);
                if (likely(clk->parent))
                        __clk_disable(clk->parent);
@@ -393,7 +396,7 @@ int clk_register(struct clk *clk)
 {
        int ret;
 
-       if (clk == NULL || IS_ERR(clk))
+       if (IS_ERR_OR_NULL(clk))
                return -EINVAL;
 
        /*
@@ -744,3 +747,25 @@ err_out:
        return err;
 }
 late_initcall(clk_debugfs_init);
+
+static int __init clk_late_init(void)
+{
+       unsigned long flags;
+       struct clk *clk;
+
+       /* disable all clocks with zero use count */
+       mutex_lock(&clock_list_sem);
+       spin_lock_irqsave(&clock_lock, flags);
+
+       list_for_each_entry(clk, &clock_list, node)
+               if (!clk->usecount && clk->ops && clk->ops->disable)
+                       clk->ops->disable(clk);
+
+       /* from now on allow clock disable operations */
+       allow_disable = 1;
+
+       spin_unlock_irqrestore(&clock_lock, flags);
+       mutex_unlock(&clock_list_sem);
+       return 0;
+}
+late_initcall(clk_late_init);