summaryrefslogtreecommitdiff
path: root/arch/arm/plat-s3c24xx/clock.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-10-21 14:06:37 +0100
committerBen Dooks <ben-linux@fluff.org>2008-12-15 21:46:07 +0000
commitc3391e36d697c997b6afeb045071e0be95219a3e (patch)
tree8bd9c12dd364519347473277496da3f3f1a54c9c /arch/arm/plat-s3c24xx/clock.c
parent305554768011707f33f437b96f999f812ba2a7e4 (diff)
[ARM] S3C24XX: Change clock locking to use spinlocks.
We cannot sleep if we have cpufreq pm enabled during some of the clock operations, so change to use a spinlock to protect the clock system. Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/plat-s3c24xx/clock.c')
-rw-r--r--arch/arm/plat-s3c24xx/clock.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index 1ff1b9836042..334e696200be 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -37,7 +37,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/clk.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -55,7 +55,11 @@
static LIST_HEAD(clocks);
-DEFINE_MUTEX(clocks_mutex);
+/* We originally used an mutex here, but some contexts (see resume)
+ * are calling functions such as clk_set_parent() with IRQs disabled
+ * causing an BUG to be triggered.
+ */
+DEFINE_SPINLOCK(clocks_lock);
/* enable and disable calls for use with the clk struct */
@@ -77,7 +81,7 @@ struct clk *clk_get(struct device *dev, const char *id)
else
idno = to_platform_device(dev)->id;
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
list_for_each_entry(p, &clocks, list) {
if (p->id == idno &&
@@ -101,7 +105,7 @@ struct clk *clk_get(struct device *dev, const char *id)
}
}
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return clk;
}
@@ -117,12 +121,12 @@ int clk_enable(struct clk *clk)
clk_enable(clk->parent);
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
if ((clk->usage++) == 0)
(clk->enable)(clk, 1);
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return 0;
}
@@ -131,12 +135,12 @@ void clk_disable(struct clk *clk)
if (IS_ERR(clk) || clk == NULL)
return;
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
if ((--clk->usage) == 0)
(clk->enable)(clk, 0);
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
clk_disable(clk->parent);
}
@@ -182,9 +186,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (clk->set_rate == NULL)
return -EINVAL;
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
ret = (clk->set_rate)(clk, rate);
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return ret;
}
@@ -201,12 +205,12 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
if (IS_ERR(clk))
return -EINVAL;
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
if (clk->set_parent)
ret = (clk->set_parent)(clk, parent);
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return ret;
}
@@ -302,9 +306,9 @@ int s3c24xx_register_clock(struct clk *clk)
/* add to the list of available clocks */
- mutex_lock(&clocks_mutex);
+ spin_lock(&clocks_lock);
list_add(&clk->list, &clocks);
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return 0;
}