Skip to contentSkip to conversation

clk fixes for 3.8

PATCH New Tony Prisk 2 participants 5 messages Dec 27, 2012 – Jan 14, 2013 Common clk

lore
Share & tools
lore

Tony Prisk

author
#0 lore raw

cover clk fixes for 3.8

Mike,

Three bugfixes for 3.8.

#1 was a boo-boo on my part, function returned the wrong variables. #2 is a truncation problem which results in a higher-than-requested clock rate. #3 became apparent when the MMC driver started requesting rate=0 during init.

Tony Prisk (3):
clk: vt8500: Fix error in PLL calculations on non-exact match.
clk: vt8500: Fix device clock divisor calculations
clk: vt8500: Fix division-by-0 when requested rate=0

 drivers/clk/clk-vt8500.c |   28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 1/3 clk: vt8500: Fix error in PLL calculations on non-exact match.

When a PLL frequency calculation is performed and a non-exact match is found the wrong multiplier and divisors are returned.

---
 drivers/clk/clk-vt8500.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/clk-vt8500.c +3 -3
index fe25570..0cb26be 100644
@@ -361,9 +361,9 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
 	/* if we got here, it wasn't an exact match */
 	pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
 							rate - best_err);
-	*multiplier = mul;
-	*divisor1 = div1;
-	*divisor2 = div2;
+	*multiplier = best_mul;
+	*divisor1 = best_div1;
+	*divisor2 = best_div2;
 }
 
 static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH 2/3 clk: vt8500: Fix device clock divisor calculations

In reply to Tony Prisk

When calculating device clock divisor values in set_rate and round_rate, we do a simple integer divide. If parent_rate / rate has a fraction, this is dropped which results in the device clock being set too high.

This patch corrects the problem by adding 1 to the calculated divisor if the division would have had a decimal result.

---
 drivers/clk/clk-vt8500.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/clk/clk-vt8500.c +8 -0
index 0cb26be..3306c2b 100644
@@ -123,6 +123,10 @@ static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
 	struct clk_device *cdev = to_clk_device(hw);
 	u32 divisor = *prate / rate;
 
+	/* If prate / rate would be decimal, incr the divisor */
+	if (rate * divisor < *prate)
+		divisor++;
+
 	/*
 	 * If this is a request for SDMMC we have to adjust the divisor
 	 * when >31 to use the fixed predivisor
@@ -141,6 +145,10 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
 	u32 divisor = parent_rate / rate;
 	unsigned long flags = 0;
 
+	/* If prate / rate would be decimal, incr the divisor */
+	if (rate * divisor < *prate)
+		divisor++;
+
 	if (divisor == cdev->div_mask + 1)
 		divisor = 0;
 
Signature · 1 line
1.7.9.5
author
#3 lore raw

PATCH 3/3 clk: vt8500: Fix division-by-0 when requested rate=0

In reply to Tony Prisk

A request to vt8500_dclk_(round_rate/set_rate) with rate=0 results in a division-by-0 in the kernel.

---
 drivers/clk/clk-vt8500.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/clk/clk-vt8500.c +12 -2
index 3306c2b..db7d41f 100644
@@ -121,7 +121,12 @@ static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long *prate)
 {
 	struct clk_device *cdev = to_clk_device(hw);
-	u32 divisor = *prate / rate;
+	u32 divisor;
+
+	if (rate == 0)
+		return 0;
+
+	divisor = *prate / rate;
 
 	/* If prate / rate would be decimal, incr the divisor */
 	if (rate * divisor < *prate)
@@ -142,9 +147,14 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
 				unsigned long parent_rate)
 {
 	struct clk_device *cdev = to_clk_device(hw);
-	u32 divisor = parent_rate / rate;
+	u32 divisor;
 	unsigned long flags = 0;
 
+	if (rate == 0)
+		return 0;
+
+	divisor =  parent_rate / rate;
+
 	/* If prate / rate would be decimal, incr the divisor */
 	if (rate * divisor < *prate)
 		divisor++;
Signature · 1 line
1.7.9.5
#4 lore raw

cover clk fixes for 3.8

In reply to Tony Prisk

Quoting Tony Prisk (2012-12-26 16:14:28)

Quoted 4 lines

Mike,

Three bugfixes for 3.8.

Tony,

I've taken these into clk-next.

Thanks,
Mike

Quoted 14 lines

#1 was a boo-boo on my part, function returned the wrong variables. #2 is a truncation problem which results in a higher-than-requested clock rate. #3 became apparent when the MMC driver started requesting rate=0 during init.

Tony Prisk (3):
clk: vt8500: Fix error in PLL calculations on non-exact match.
clk: vt8500: Fix device clock divisor calculations
clk: vt8500: Fix division-by-0 when requested rate=0

 drivers/clk/clk-vt8500.c |   28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)
Signature · 1 line
1.7.9.5