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>
This commit is contained in:

committed by
Kevin Hilman

parent
00642f6616
commit
3b43cd6f2d
@@ -125,9 +125,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
if (clk == NULL || IS_ERR(clk))
|
||||
return ret;
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (clk->set_rate)
|
||||
ret = clk->set_rate(clk, rate);
|
||||
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
if (ret == 0) {
|
||||
if (clk->recalc)
|
||||
clk->rate = clk->recalc(clk);
|
||||
@@ -364,6 +365,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
{
|
||||
u32 ctrl;
|
||||
unsigned int locktime;
|
||||
unsigned long flags;
|
||||
|
||||
if (pll->base == NULL)
|
||||
return -EINVAL;
|
||||
@@ -384,6 +386,9 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
if (mult)
|
||||
mult = mult - 1;
|
||||
|
||||
/* Protect against simultaneous calls to PLL setting seqeunce */
|
||||
spin_lock_irqsave(&clockfw_lock, flags);
|
||||
|
||||
ctrl = __raw_readl(pll->base + PLLCTL);
|
||||
|
||||
/* Switch the PLL to bypass mode */
|
||||
@@ -416,6 +421,8 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
|
||||
ctrl |= PLLCTL_PLLEN;
|
||||
__raw_writel(ctrl, pll->base + PLLCTL);
|
||||
|
||||
spin_unlock_irqrestore(&clockfw_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(davinci_set_pllrate);
|
||||
|
Reference in New Issue
Block a user