aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/clock.c
diff options
context:
space:
mode:
authorSekhar Nori <nsekhar@ti.com>2010-01-12 08:25:35 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-02-04 16:30:08 -0500
commit3b43cd6f2dcbf871b8cabe16ae4ac8c036c959ac (patch)
tree064252da18333283fc12e088f37b94fc6c74e24e /arch/arm/mach-davinci/clock.c
parent00642f6616a0d1893ab1dcfec4d833210f310e95 (diff)
davinci: clock: let clk->set_rate function sleep
When supporting I2C/SPI based on-board PLLs like CDCE949, it is essential that clk->set_rate be able to sleep. Currently, this is not possible because clk->set_rate is called from within spin-lock in clk_set_rate This patch brings clk->set_rate outside of the spin-lock and lets the individual set_rate implementations achieve serialization through appropiate means. Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci/clock.c')
-rw-r--r--arch/arm/mach-davinci/clock.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 123839332d50..0fc63f93a222 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -125,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
125 if (clk == NULL || IS_ERR(clk)) 125 if (clk == NULL || IS_ERR(clk))
126 return ret; 126 return ret;
127 127
128 spin_lock_irqsave(&clockfw_lock, flags);
129 if (clk->set_rate) 128 if (clk->set_rate)
130 ret = clk->set_rate(clk, rate); 129 ret = clk->set_rate(clk, rate);
130
131 spin_lock_irqsave(&clockfw_lock, flags);
131 if (ret == 0) { 132 if (ret == 0) {
132 if (clk->recalc) 133 if (clk->recalc)
133 clk->rate = clk->recalc(clk); 134 clk->rate = clk->recalc(clk);
@@ -364,6 +365,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
364{ 365{
365 u32 ctrl; 366 u32 ctrl;
366 unsigned int locktime; 367 unsigned int locktime;
368 unsigned long flags;
367 369
368 if (pll->base == NULL) 370 if (pll->base == NULL)
369 return -EINVAL; 371 return -EINVAL;
@@ -384,6 +386,9 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
384 if (mult) 386 if (mult)
385 mult = mult - 1; 387 mult = mult - 1;
386 388
389 /* Protect against simultaneous calls to PLL setting seqeunce */
390 spin_lock_irqsave(&clockfw_lock, flags);
391
387 ctrl = __raw_readl(pll->base + PLLCTL); 392 ctrl = __raw_readl(pll->base + PLLCTL);
388 393
389 /* Switch the PLL to bypass mode */ 394 /* Switch the PLL to bypass mode */
@@ -416,6 +421,8 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
416 ctrl |= PLLCTL_PLLEN; 421 ctrl |= PLLCTL_PLLEN;
417 __raw_writel(ctrl, pll->base + PLLCTL); 422 __raw_writel(ctrl, pll->base + PLLCTL);
418 423
424 spin_unlock_irqrestore(&clockfw_lock, flags);
425
419 return 0; 426 return 0;
420} 427}
421EXPORT_SYMBOL(davinci_set_pllrate); 428EXPORT_SYMBOL(davinci_set_pllrate);