clk: divider: Introduce CLK_DIVIDER_ALLOW_ZERO flag
authorSoren Brinkmann <soren.brinkmann@xilinx.com>
Tue, 2 Apr 2013 22:36:56 +0000 (15:36 -0700)
committerMike Turquette <mturquette@linaro.org>
Wed, 3 Apr 2013 19:56:30 +0000 (12:56 -0700)
Dividers which have CLK_DIVIDER_ONE_BASED set have a redundant state,
being a divider value of zero. Some hardware implementations allow a
zero divider which simply doesn't alter the frequency. I.e. it acts like
a divide by one or bypassing the divider.
This flag is used to handle such HW in the clk-divider model.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
drivers/clk/clk-divider.c
include/linux/clk-provider.h

index 68b402101170f48c2e0ecda98c38f018247c1946..6d9674160430db7456b58c1697272a801b68ba52 100644 (file)
@@ -109,8 +109,9 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
 
        div = _get_div(divider, val);
        if (!div) {
-               WARN(1, "%s: Invalid divisor for clock %s\n", __func__,
-                                               __clk_get_name(hw->clk));
+               WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
+                       "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
+                       __clk_get_name(hw->clk));
                return parent_rate;
        }
 
index b1675074fe7c2183341fae171c9b456495cdf5aa..9fdfae74d6698b76026d58d4dc6673b95957fa89 100644 (file)
@@ -249,9 +249,14 @@ struct clk_div_table {
  * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the
  *     register plus one.  If CLK_DIVIDER_ONE_BASED is set then the divider is
  *     the raw value read from the register, with the value of zero considered
- *     invalid
+ *     invalid, unless CLK_DIVIDER_ALLOW_ZERO is set.
  * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from
  *     the hardware register
+ * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors.  For dividers which have
+ *     CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor.
+ *     Some hardware implementations gracefully handle this case and allow a
+ *     zero divisor by not modifying their input clock
+ *     (divide by one / bypass).
  */
 struct clk_divider {
        struct clk_hw   hw;
@@ -265,6 +270,7 @@ struct clk_divider {
 
 #define CLK_DIVIDER_ONE_BASED          BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO       BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO         BIT(2)
 
 extern const struct clk_ops clk_divider_ops;
 struct clk *clk_register_divider(struct device *dev, const char *name,