mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks
@ 2026-09-01 12:53 Linkai Gong
  2026-09-07 12:58 ` Michal Simek
  2026-09-08  8:47 ` [PATCH v2] " Linkai Gong
  0 siblings, 2 replies; 4+ messages in thread
From: Linkai Gong @ 2026-09-01 12:53 UTC (permalink / raw)
  To: Stephen Boyd, Brian Masney, Jerome Brunet, Michal Simek
  Cc: Kees Cook, Babanpreet Singh, Mike Turquette, Soren Brinkmann,
	linux-clk, linux-arm-kernel, linux-kernel, gonglinkai

zynq_pll_enable() waits for lock under a spinlock with no
timeout. Poll with a 1ms bound and return the error.

Fixes: 3682af46d55f ("clk: zynq: Factor out PLL driver")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
---
 drivers/clk/zynq/pll.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
index 44c609378364..96cf45088ba0 100644
--- a/drivers/clk/zynq/pll.c
+++ b/drivers/clk/zynq/pll.c
@@ -10,6 +10,7 @@
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 
 /**
  * struct zynq_pll - pll clock
@@ -119,6 +120,7 @@ static int zynq_pll_enable(struct clk_hw *hw)
 	unsigned long flags = 0;
 	u32 reg;
 	struct zynq_pll *clk = to_zynq_pll(hw);
+	int ret;
 
 	if (zynq_pll_is_enabled(hw))
 		return 0;
@@ -131,12 +133,12 @@ static int zynq_pll_enable(struct clk_hw *hw)
 	reg = readl(clk->pll_ctrl);
 	reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
 	writel(reg, clk->pll_ctrl);
-	while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
-		;
+	ret = readl_poll_timeout_atomic(clk->pll_status, reg,
+					reg & (1 << clk->lockbit), 10, 1000);
 
 	spin_unlock_irqrestore(clk->lock, flags);
 
-	return 0;
+	return ret;
 }
 
 /**
-- 
2.25.1


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

* Re: [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks
  2026-09-01 12:53 [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks Linkai Gong
@ 2026-09-07 12:58 ` Michal Simek
  2026-09-08  8:44   ` Linkai Gong
  2026-09-08  8:47 ` [PATCH v2] " Linkai Gong
  1 sibling, 1 reply; 4+ messages in thread
From: Michal Simek @ 2026-09-07 12:58 UTC (permalink / raw)
  To: Linkai Gong, Stephen Boyd, Brian Masney, Jerome Brunet
  Cc: Kees Cook, Babanpreet Singh, Mike Turquette, Soren Brinkmann,
	linux-clk, linux-arm-kernel, linux-kernel



On 9/1/26 14:53, Linkai Gong wrote:
> zynq_pll_enable() waits for lock under a spinlock with no
> timeout. Poll with a 1ms bound and return the error.
> 
> Fixes: 3682af46d55f ("clk: zynq: Factor out PLL driver")
> Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
> ---
>   drivers/clk/zynq/pll.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
> index 44c609378364..96cf45088ba0 100644
> --- a/drivers/clk/zynq/pll.c
> +++ b/drivers/clk/zynq/pll.c
> @@ -10,6 +10,7 @@
>   #include <linux/clk-provider.h>
>   #include <linux/slab.h>
>   #include <linux/io.h>
> +#include <linux/iopoll.h>
>   
>   /**
>    * struct zynq_pll - pll clock
> @@ -119,6 +120,7 @@ static int zynq_pll_enable(struct clk_hw *hw)
>   	unsigned long flags = 0;
>   	u32 reg;
>   	struct zynq_pll *clk = to_zynq_pll(hw);
> +	int ret;
>   
>   	if (zynq_pll_is_enabled(hw))
>   		return 0;
> @@ -131,12 +133,12 @@ static int zynq_pll_enable(struct clk_hw *hw)
>   	reg = readl(clk->pll_ctrl);
>   	reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
>   	writel(reg, clk->pll_ctrl);
> -	while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
> -		;
> +	ret = readl_poll_timeout_atomic(clk->pll_status, reg,
> +					reg & (1 << clk->lockbit), 10, 1000);

BIT(clk->lockbit)

And 10 and 1000 are magic values.

Fix itself is fine but I would prefer to explain more why 1ms upper limit was 
used. I don't think it is going to be a problem and 10-1000us is fine. I just 
want to make sure that it will be clear that this value is not coming from any 
TRM but still at least range is aligned with expectation in HW.

Thanks,
Michal


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

* Re: [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks
  2026-09-07 12:58 ` Michal Simek
@ 2026-09-08  8:44   ` Linkai Gong
  0 siblings, 0 replies; 4+ messages in thread
From: Linkai Gong @ 2026-09-08  8:44 UTC (permalink / raw)
  To: Michal Simek
  Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Mike Turquette,
	Soren Brinkmann, Kees Cook, Babanpreet Singh, linux-clk,
	linux-arm-kernel, linux-kernel, gonglinkai

On Mon, Sep 07, 2026 at 02:58:18PM +0200, Michal Simek wrote:
> BIT(clk->lockbit)
>
> And 10 and 1000 are magic values.
>
> Fix itself is fine but I would prefer to explain more why 1ms upper limit was
> used. I don't think it is going to be a problem and 10-1000us is fine. I just
> want to make sure that it will be clear that this value is not coming from any
> TRM but still at least range is aligned with expectation in HW.

Thanks for the review.

Agreed on both points. v2 will use BIT(), name the poll delay/timeout,
and clarify in the commit message that 1 ms is a software upper bound
for a stuck PLL under spinlock, not a TRM-derived value; lock is still
expected well within that window on Zynq.

Will send v2 shortly.

Thanks,
Linkai

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

* [PATCH v2] clk: zynq: return -ETIMEDOUT if the PLL never locks
  2026-09-01 12:53 [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks Linkai Gong
  2026-09-07 12:58 ` Michal Simek
@ 2026-09-08  8:47 ` Linkai Gong
  1 sibling, 0 replies; 4+ messages in thread
From: Linkai Gong @ 2026-09-08  8:47 UTC (permalink / raw)
  To: Michal Simek, Stephen Boyd, Brian Masney, Jerome Brunet
  Cc: Mike Turquette, Soren Brinkmann, Kees Cook, Babanpreet Singh,
	linux-clk, linux-arm-kernel, linux-kernel, gonglinkai

zynq_pll_enable() waits for lock under a spinlock with no timeout.
A stuck PLL would wedge the enable path with IRQs off.

Poll with readl_poll_timeout_atomic() and return -ETIMEDOUT on
failure. The 1 ms upper bound is a software limit for a stuck PLL,
not a TRM-derived value; Zynq PLL lock is still expected well
within that window.

Changes in v2:
- Use BIT(clk->lockbit)
- Name the poll delay/timeout constants
- Clarify the 1 ms bound in the commit message

Fixes: 3682af46d55f ("clk: zynq: Factor out PLL driver")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
---
 drivers/clk/zynq/pll.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
index fe90b50e1545..6a98bc60fb91 100644
--- a/drivers/clk/zynq/pll.c
+++ b/drivers/clk/zynq/pll.c
@@ -9,7 +9,9 @@
 #include <linux/clk/zynq.h>
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
+#include <linux/bits.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 
 /**
  * struct zynq_pll - pll clock
@@ -41,6 +43,10 @@ struct zynq_pll {
 #define PLL_FBDIV_MIN	13
 #define PLL_FBDIV_MAX	66
 
+/* Software bound for a stuck PLL under spinlock; not from the TRM. */
+#define PLL_LOCK_POLL_DELAY_US	10
+#define PLL_LOCK_TIMEOUT_US	1000
+
 /**
  * zynq_pll_determine_rate() - Round a clock frequency
  * @hw:		Handle between common and hardware-specific interfaces
@@ -119,6 +125,7 @@ static int zynq_pll_enable(struct clk_hw *hw)
 	unsigned long flags = 0;
 	u32 reg;
 	struct zynq_pll *clk = to_zynq_pll(hw);
+	int ret;
 
 	if (zynq_pll_is_enabled(hw))
 		return 0;
@@ -131,12 +138,14 @@ static int zynq_pll_enable(struct clk_hw *hw)
 	reg = readl(clk->pll_ctrl);
 	reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
 	writel(reg, clk->pll_ctrl);
-	while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
-		;
+	ret = readl_poll_timeout_atomic(clk->pll_status, reg,
+					reg & BIT(clk->lockbit),
+					PLL_LOCK_POLL_DELAY_US,
+					PLL_LOCK_TIMEOUT_US);
 
 	spin_unlock_irqrestore(clk->lock, flags);
 
-	return 0;
+	return ret;
 }
 
 /**
-- 
2.25.1

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

end of thread, other threads:[~2026-09-08  8:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-01 12:53 [PATCH] clk: zynq: return -ETIMEDOUT if the PLL never locks Linkai Gong
2026-09-07 12:58 ` Michal Simek
2026-09-08  8:44   ` Linkai Gong
2026-09-08  8:47 ` [PATCH v2] " Linkai Gong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®