]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
clk: pass parent_rate into .set_rate
authorShawn Guo <shawn.guo@linaro.org>
Thu, 12 Apr 2012 12:50:18 +0000 (20:50 +0800)
committerMike Turquette <mturquette@linaro.org>
Tue, 24 Apr 2012 23:37:40 +0000 (16:37 -0700)
For most of .set_rate implementation, parent_rate will be used, so just
like passing parent_rate into .recalc_rate, let's pass parent_rate into
.set_rate too.

It also updates the kernel doc for .set_rate ops.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
drivers/clk/clk-divider.c
drivers/clk/clk.c
include/linux/clk-provider.h

index 03b127c0313b3e38e2d685c7624eb1d99b98ba46..90627e4069af08cb756066298d5784c656aad8ff 100644 (file)
@@ -111,14 +111,15 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
        return *prate / div;
 }
 
-static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate)
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
 {
        struct clk_divider *divider = to_clk_divider(hw);
        unsigned int div;
        unsigned long flags = 0;
        u32 val;
 
-       div = __clk_get_rate(__clk_get_parent(hw->clk)) / rate;
+       div = parent_rate / rate;
 
        if (!(divider->flags & CLK_DIVIDER_ONE_BASED))
                div--;
index 1ab4f7e5c7ef80735a4c8cbac57e9ed042fd5cf3..62ecac53b0a236be9cc45d9cd85a2841419b9247 100644 (file)
@@ -848,7 +848,7 @@ static void clk_change_rate(struct clk *clk)
        old_rate = clk->rate;
 
        if (clk->ops->set_rate)
-               clk->ops->set_rate(clk->hw, clk->new_rate);
+               clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate);
 
        if (clk->ops->recalc_rate)
                clk->rate = clk->ops->recalc_rate(clk->hw,
index 3323d24a7be4197409632054f7d43a6ca06bbddc..cb82918d8fe04d36e73ec636bdc7f62d88a8f159 100644 (file)
@@ -88,19 +88,11 @@ struct clk_hw {
  *             array index into the value programmed into the hardware.
  *             Returns 0 on success, -EERROR otherwise.
  *
- * @set_rate:  Change the rate of this clock. If this callback returns
- *             CLK_SET_RATE_PARENT, the rate change will be propagated to the
- *             parent clock (which may propagate again if the parent clock
- *             also sets this flag). The requested rate of the parent is
- *             passed back from the callback in the second 'unsigned long *'
- *             argument.  Note that it is up to the hardware clock's set_rate
- *             implementation to insure that clocks do not run out of spec
- *             when propgating the call to set_rate up to the parent.  One way
- *             to do this is to gate the clock (via clk_disable and/or
- *             clk_unprepare) before calling clk_set_rate, then ungating it
- *             afterward.  If your clock also has the CLK_GATE_SET_RATE flag
- *             set then this will insure safety.  Returns 0 on success,
- *             -EERROR otherwise.
+ * @set_rate:  Change the rate of this clock. The requested rate is specified
+ *             by the second argument, which should typically be the return
+ *             of .round_rate call.  The third argument gives the parent rate
+ *             which is likely helpful for most .set_rate implementation.
+ *             Returns 0 on success, -EERROR otherwise.
  *
  * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
  * implementations to split any work between atomic (enable) and sleepable
@@ -125,7 +117,8 @@ struct clk_ops {
                                        unsigned long *);
        int             (*set_parent)(struct clk_hw *hw, u8 index);
        u8              (*get_parent)(struct clk_hw *hw);
-       int             (*set_rate)(struct clk_hw *hw, unsigned long);
+       int             (*set_rate)(struct clk_hw *hw, unsigned long,
+                                   unsigned long);
        void            (*init)(struct clk_hw *hw);
 };