|
@@ -81,9 +81,19 @@ static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
|
|
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
|
|
- unsigned long ideal = rate * i;
|
|
|
|
|
|
+ u64 ideal = (u64)rate * i;
|
|
unsigned long rounded;
|
|
unsigned long rounded;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * ideal has overflowed the max value that can be stored in an
|
|
|
|
+ * unsigned long, and every clk operation we might do on a
|
|
|
|
+ * truncated u64 value will give us incorrect results.
|
|
|
|
+ * Let's just stop there since bigger dividers will result in
|
|
|
|
+ * the same overflow issue.
|
|
|
|
+ */
|
|
|
|
+ if (ideal > ULONG_MAX)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
|
|
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
|
|
ideal);
|
|
ideal);
|
|
|
|
|