linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] clk fixes for 3.8
@ 2012-12-27  0:14 Tony Prisk
  2012-12-27  0:14 ` [PATCH 1/3] clk: vt8500: Fix error in PLL calculations on non-exact match Tony Prisk
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Tony Prisk @ 2012-12-27  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

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(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] clk: vt8500: Fix error in PLL calculations on non-exact match.
  2012-12-27  0:14 [PATCH 0/3] clk fixes for 3.8 Tony Prisk
@ 2012-12-27  0:14 ` Tony Prisk
  2012-12-27  0:14 ` [PATCH 2/3] clk: vt8500: Fix device clock divisor calculations Tony Prisk
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Tony Prisk @ 2012-12-27  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/clk/clk-vt8500.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index fe25570..0cb26be 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -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,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] clk: vt8500: Fix device clock divisor calculations
  2012-12-27  0:14 [PATCH 0/3] clk fixes for 3.8 Tony Prisk
  2012-12-27  0:14 ` [PATCH 1/3] clk: vt8500: Fix error in PLL calculations on non-exact match Tony Prisk
@ 2012-12-27  0:14 ` Tony Prisk
  2012-12-27  0:14 ` [PATCH 3/3] clk: vt8500: Fix division-by-0 when requested rate=0 Tony Prisk
  2013-01-14 23:06 ` [PATCH 0/3] clk fixes for 3.8 Mike Turquette
  3 siblings, 0 replies; 5+ messages in thread
From: Tony Prisk @ 2012-12-27  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/clk/clk-vt8500.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index 0cb26be..3306c2b 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -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;
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] clk: vt8500: Fix division-by-0 when requested rate=0
  2012-12-27  0:14 [PATCH 0/3] clk fixes for 3.8 Tony Prisk
  2012-12-27  0:14 ` [PATCH 1/3] clk: vt8500: Fix error in PLL calculations on non-exact match Tony Prisk
  2012-12-27  0:14 ` [PATCH 2/3] clk: vt8500: Fix device clock divisor calculations Tony Prisk
@ 2012-12-27  0:14 ` Tony Prisk
  2013-01-14 23:06 ` [PATCH 0/3] clk fixes for 3.8 Mike Turquette
  3 siblings, 0 replies; 5+ messages in thread
From: Tony Prisk @ 2012-12-27  0:14 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/clk/clk-vt8500.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c
index 3306c2b..db7d41f 100644
--- a/drivers/clk/clk-vt8500.c
+++ b/drivers/clk/clk-vt8500.c
@@ -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++;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 0/3] clk fixes for 3.8
  2012-12-27  0:14 [PATCH 0/3] clk fixes for 3.8 Tony Prisk
                   ` (2 preceding siblings ...)
  2012-12-27  0:14 ` [PATCH 3/3] clk: vt8500: Fix division-by-0 when requested rate=0 Tony Prisk
@ 2013-01-14 23:06 ` Mike Turquette
  3 siblings, 0 replies; 5+ messages in thread
From: Mike Turquette @ 2013-01-14 23:06 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Tony Prisk (2012-12-26 16:14:28)
> Mike,
> 
> Three bugfixes for 3.8.
> 

Tony,

I've taken these into clk-next.

Thanks,
Mike

> #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(-)
> 
> -- 
> 1.7.9.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-14 23:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-27  0:14 [PATCH 0/3] clk fixes for 3.8 Tony Prisk
2012-12-27  0:14 ` [PATCH 1/3] clk: vt8500: Fix error in PLL calculations on non-exact match Tony Prisk
2012-12-27  0:14 ` [PATCH 2/3] clk: vt8500: Fix device clock divisor calculations Tony Prisk
2012-12-27  0:14 ` [PATCH 3/3] clk: vt8500: Fix division-by-0 when requested rate=0 Tony Prisk
2013-01-14 23:06 ` [PATCH 0/3] clk fixes for 3.8 Mike Turquette

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).