Skip to content

Commit 78f6f40

Browse files
robhancocksedbebarino
authored andcommitted
clk: si5341: Avoid divide errors due to bogus register contents
If the Si5341 is being initially programmed and has no stored NVM configuration, some of the register contents may contain unexpected values, such as zeros, which could cause divide by zero errors during driver initialization. Trap errors caused by zero registers or zero clock rates which could result in divide errors later in the code. Fixes: 3044a86 ("clk: Add Si5341/Si5340 driver") Signed-off-by: Robert Hancock <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 6e7d2de commit 78f6f40

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

drivers/clk/clk-si5341.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,9 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw,
624624
SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den);
625625
if (err < 0)
626626
return err;
627+
/* Check for bogus/uninitialized settings */
628+
if (!n_num || !n_den)
629+
return 0;
627630

628631
/*
629632
* n_num and n_den are shifted left as much as possible, so to prevent
@@ -807,6 +810,9 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate,
807810
{
808811
unsigned long r;
809812

813+
if (!rate)
814+
return 0;
815+
810816
r = *parent_rate >> 1;
811817

812818
/* If rate is an even divisor, no changes to parent required */
@@ -835,11 +841,16 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate,
835841
unsigned long parent_rate)
836842
{
837843
struct clk_si5341_output *output = to_clk_si5341_output(hw);
838-
/* Frequency divider is (r_div + 1) * 2 */
839-
u32 r_div = (parent_rate / rate) >> 1;
844+
u32 r_div;
840845
int err;
841846
u8 r[3];
842847

848+
if (!rate)
849+
return -EINVAL;
850+
851+
/* Frequency divider is (r_div + 1) * 2 */
852+
r_div = (parent_rate / rate) >> 1;
853+
843854
if (r_div <= 1)
844855
r_div = 0;
845856
else if (r_div >= BIT(24))

0 commit comments

Comments
 (0)