]> Pileus Git - ~andy/linux/blobdiff - arch/arm/plat-mxc/clock.c
Merge tag 'sound-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[~andy/linux] / arch / arm / plat-mxc / clock.c
index 323ff8ccc877161042a72bbf309c955878160966..2ed3ab173addcae894a1c52190e7cc9419dddc90 100644 (file)
@@ -52,13 +52,14 @@ static void __clk_disable(struct clk *clk)
 {
        if (clk == NULL || IS_ERR(clk))
                return;
-
-       __clk_disable(clk->parent);
-       __clk_disable(clk->secondary);
-
        WARN_ON(!clk->usecount);
-       if (!(--clk->usecount) && clk->disable)
-               clk->disable(clk);
+
+       if (!(--clk->usecount)) {
+               if (clk->disable)
+                       clk->disable(clk);
+               __clk_disable(clk->parent);
+               __clk_disable(clk->secondary);
+       }
 }
 
 static int __clk_enable(struct clk *clk)
@@ -66,12 +67,13 @@ static int __clk_enable(struct clk *clk)
        if (clk == NULL || IS_ERR(clk))
                return -EINVAL;
 
-       __clk_enable(clk->parent);
-       __clk_enable(clk->secondary);
-
-       if (clk->usecount++ == 0 && clk->enable)
-               clk->enable(clk);
+       if (clk->usecount++ == 0) {
+               __clk_enable(clk->parent);
+               __clk_enable(clk->secondary);
 
+               if (clk->enable)
+                       clk->enable(clk);
+       }
        return 0;
 }
 
@@ -160,17 +162,28 @@ EXPORT_SYMBOL(clk_set_rate);
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
        int ret = -EINVAL;
+       struct clk *old;
 
        if (clk == NULL || IS_ERR(clk) || parent == NULL ||
            IS_ERR(parent) || clk->set_parent == NULL)
                return ret;
 
+       if (clk->usecount)
+               clk_enable(parent);
+
        mutex_lock(&clocks_mutex);
        ret = clk->set_parent(clk, parent);
-       if (ret == 0)
+       if (ret == 0) {
+               old = clk->parent;
                clk->parent = parent;
+       } else {
+               old = parent;
+       }
        mutex_unlock(&clocks_mutex);
 
+       if (clk->usecount)
+               clk_disable(old);
+
        return ret;
 }
 EXPORT_SYMBOL(clk_set_parent);