clk: Introduce optional unprepare_unused callback
authorUlf Hansson <ulf.hansson@linaro.org>
Tue, 12 Mar 2013 19:26:04 +0000 (20:26 +0100)
committerMike Turquette <mturquette@linaro.org>
Tue, 19 Mar 2013 19:58:43 +0000 (12:58 -0700)
An unprepare_unused callback is introduced due to the same reasons to
why the disable_unused callback was added.

During the clk_disable_unused sequence, those clk_hw that needs specific
treatment with regards to being unprepared, shall implement the
unprepare_unused callback.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
drivers/clk/clk.c
include/linux/clk-provider.h

index c0141f3..253792a 100644 (file)
@@ -352,9 +352,12 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
        if (clk->flags & CLK_IGNORE_UNUSED)
                return;
 
-       if (__clk_is_prepared(clk))
-               if (clk->ops->unprepare)
+       if (__clk_is_prepared(clk)) {
+               if (clk->ops->unprepare_unused)
+                       clk->ops->unprepare_unused(clk->hw);
+               else if (clk->ops->unprepare)
                        clk->ops->unprepare(clk->hw);
+       }
 }
 
 /* caller must hold prepare_lock */
index ee94686..56e6cc1 100644 (file)
@@ -49,6 +49,10 @@ struct clk_hw;
  *             This function is allowed to sleep. Optional, if this op is not
  *             set then the prepare count will be used.
  *
+ * @unprepare_unused: Unprepare the clock atomically.  Only called from
+ *             clk_disable_unused for prepare clocks with special needs.
+ *             Called with prepare mutex held. This function may sleep.
+ *
  * @enable:    Enable the clock atomically. This must not return until the
  *             clock is generating a valid clock signal, usable by consumer
  *             devices. Called with enable_lock held. This function must not
@@ -113,6 +117,7 @@ struct clk_ops {
        int             (*prepare)(struct clk_hw *hw);
        void            (*unprepare)(struct clk_hw *hw);
        int             (*is_prepared)(struct clk_hw *hw);
+       void            (*unprepare_unused)(struct clk_hw *hw);
        int             (*enable)(struct clk_hw *hw);
        void            (*disable)(struct clk_hw *hw);
        int             (*is_enabled)(struct clk_hw *hw);