clk: si5341: fix reported clk_rate when output divider is 2
authorAdam Wujek <dev_public@wujek.eu>
Fri, 3 Dec 2021 14:12:07 +0000 (14:12 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Apr 2022 18:59:10 +0000 (20:59 +0200)
[ Upstream commit 2a8b539433e111c4de364237627ef219d2f6350a ]

SI5341_OUT_CFG_RDIV_FORCE2 shall be checked first to distinguish whether
a divider for a given output is set to 2 (SI5341_OUT_CFG_RDIV_FORCE2
is set) or the output is disabled (SI5341_OUT_CFG_RDIV_FORCE2 not set,
SI5341_OUT_R_REG is set 0).
Before the change, divider set to 2 (SI5341_OUT_R_REG set to 0) was
interpreted as output is disabled.

Signed-off-by: Adam Wujek <dev_public@wujek.eu>
Link: https://lore.kernel.org/r/20211203141125.2447520-1-dev_public@wujek.eu
Reviewed-by: Robert Hancock <robert.hancock@calian.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/clk/clk-si5341.c

index f7b4136..4de098b 100644 (file)
@@ -798,6 +798,15 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw,
        u32 r_divider;
        u8 r[3];
 
+       err = regmap_read(output->data->regmap,
+                       SI5341_OUT_CONFIG(output), &val);
+       if (err < 0)
+               return err;
+
+       /* If SI5341_OUT_CFG_RDIV_FORCE2 is set, r_divider is 2 */
+       if (val & SI5341_OUT_CFG_RDIV_FORCE2)
+               return parent_rate / 2;
+
        err = regmap_bulk_read(output->data->regmap,
                        SI5341_OUT_R_REG(output), r, 3);
        if (err < 0)
@@ -814,13 +823,6 @@ static unsigned long si5341_output_clk_recalc_rate(struct clk_hw *hw,
        r_divider += 1;
        r_divider <<= 1;
 
-       err = regmap_read(output->data->regmap,
-                       SI5341_OUT_CONFIG(output), &val);
-       if (err < 0)
-               return err;
-
-       if (val & SI5341_OUT_CFG_RDIV_FORCE2)
-               r_divider = 2;
 
        return parent_rate / r_divider;
 }