diff mbox

davinci: clock: let clk->set_rate function sleep

Message ID 1263302735-5020-1-git-send-email-nsekhar@ti.com (mailing list archive)
State Accepted
Headers show

Commit Message

Sekhar Nori Jan. 12, 2010, 1:25 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c
index 6af3289..aec3756 100644
--- a/arch/arm/mach-davinci/cdce949.c
+++ b/arch/arm/mach-davinci/cdce949.c
@@ -23,6 +23,7 @@ 
 #include "clock.h"
 
 static struct i2c_client *cdce_i2c_client;
+static DEFINE_MUTEX(cdce_mutex);
 
 /* CDCE register descriptor */
 struct cdce_reg {
@@ -231,16 +232,19 @@  int cdce_set_rate(struct clk *clk, unsigned long rate)
 	if (!regs)
 		return -EINVAL;
 
+	mutex_lock(&cdce_mutex);
 	for (i = 0; regs[i].addr; i++) {
 		ret = i2c_smbus_write_byte_data(cdce_i2c_client,
 					regs[i].addr | 0x80, regs[i].val);
 		if (ret)
-			return ret;
+			break;
 	}
+	mutex_unlock(&cdce_mutex);
 
-	clk->rate = rate;
+	if (!ret)
+		clk->rate = rate;
 
-	return 0;
+	return ret;
 }
 
 static int cdce_probe(struct i2c_client *client,
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 79d6ec8..bf6218e 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)
 	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);