diff options
author | Sekhar Nori <nsekhar@ti.com> | 2010-01-12 08:25:35 -0500 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-02-04 16:30:08 -0500 |
commit | 3b43cd6f2dcbf871b8cabe16ae4ac8c036c959ac (patch) | |
tree | 064252da18333283fc12e088f37b94fc6c74e24e /arch/arm/mach-davinci/cdce949.c | |
parent | 00642f6616a0d1893ab1dcfec4d833210f310e95 (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/cdce949.c')
-rw-r--r-- | arch/arm/mach-davinci/cdce949.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c index 6af3289e0527..aec375690543 100644 --- a/arch/arm/mach-davinci/cdce949.c +++ b/arch/arm/mach-davinci/cdce949.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "clock.h" | 23 | #include "clock.h" |
24 | 24 | ||
25 | static struct i2c_client *cdce_i2c_client; | 25 | static struct i2c_client *cdce_i2c_client; |
26 | static DEFINE_MUTEX(cdce_mutex); | ||
26 | 27 | ||
27 | /* CDCE register descriptor */ | 28 | /* CDCE register descriptor */ |
28 | struct cdce_reg { | 29 | struct cdce_reg { |
@@ -231,16 +232,19 @@ int cdce_set_rate(struct clk *clk, unsigned long rate) | |||
231 | if (!regs) | 232 | if (!regs) |
232 | return -EINVAL; | 233 | return -EINVAL; |
233 | 234 | ||
235 | mutex_lock(&cdce_mutex); | ||
234 | for (i = 0; regs[i].addr; i++) { | 236 | for (i = 0; regs[i].addr; i++) { |
235 | ret = i2c_smbus_write_byte_data(cdce_i2c_client, | 237 | ret = i2c_smbus_write_byte_data(cdce_i2c_client, |
236 | regs[i].addr | 0x80, regs[i].val); | 238 | regs[i].addr | 0x80, regs[i].val); |
237 | if (ret) | 239 | if (ret) |
238 | return ret; | 240 | break; |
239 | } | 241 | } |
242 | mutex_unlock(&cdce_mutex); | ||
240 | 243 | ||
241 | clk->rate = rate; | 244 | if (!ret) |
245 | clk->rate = rate; | ||
242 | 246 | ||
243 | return 0; | 247 | return ret; |
244 | } | 248 | } |
245 | 249 | ||
246 | static int cdce_probe(struct i2c_client *client, | 250 | static int cdce_probe(struct i2c_client *client, |