summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-01-28 12:08:46 -0700
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-08 17:50:35 +0000
commit416db864c18343c6dcc5e9768c902460c8f8777c (patch)
treef3657b727d61321f32eb1bd2efe757d73eb22795
parent95f538ac370d9625457ba00ef7c3bb91e2b92f89 (diff)
[ARM] OMAP3 clock: disable DPLL autoidle while waiting for DPLL to lock
During _omap3_noncore_dpll_lock(), if a DPLL has no active downstream clocks and DPLL autoidle is enabled, the DPLL may never lock, since it will enter autoidle immediately. To resolve this, disable DPLL autoidle while locking the DPLL, and unconditionally wait for the DPLL to lock. This fixes some bugs where the kernel would hang when returning from retention or return the wrong rate for the DPLL. This patch is a collaboration with Peter de Schrijver <peter.de-schrijver@nokia.com> and Kevin Hilman <khilman@deeprootsystems.com>. linux-omap source commit is 3b7de4be879f1f4f55ae59882a5cbd80f6dcf0f0. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Peter de Schrijver <peter.de-schrijver@nokia.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-omap2/clock34xx.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index aad77e0d43c..3d756babb2f 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -398,19 +398,14 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
ai = omap3_dpll_autoidle_read(clk);
+ omap3_dpll_deny_idle(clk);
+
_omap3_dpll_write_clken(clk, DPLL_LOCKED);
- if (ai) {
- /*
- * If no downstream clocks are enabled, CM_IDLEST bit
- * may never become active, so don't wait for DPLL to lock.
- */
- r = 0;
+ r = _omap3_wait_dpll_status(clk, 1);
+
+ if (ai)
omap3_dpll_allow_idle(clk);
- } else {
- r = _omap3_wait_dpll_status(clk, 1);
- omap3_dpll_deny_idle(clk);
- };
return r;
}