[ARM] S3C24XX: Change clock locking to use spinlocks.
[deliverable/linux.git] / arch / arm / plat-s3c24xx / clock.c
index bf2633bd39969b33ba5204d67c14d0d25ea7c0cb..334e696200be492be0f237adf00d9068a5d18278 100644 (file)
@@ -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>
 
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
+#include <plat/pll.h>
 
 /* clock information */
 
 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 */
 
@@ -76,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 &&
@@ -100,7 +105,7 @@ struct clk *clk_get(struct device *dev, const char *id)
                }
        }
 
-       mutex_unlock(&clocks_mutex);
+       spin_unlock(&clocks_lock);
        return clk;
 }
 
@@ -116,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;
 }
 
@@ -130,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);
 }
 
@@ -181,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;
 }
@@ -200,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;
 }
@@ -301,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;
 }
@@ -332,7 +337,7 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
        /* initialise the main system clocks */
 
        clk_xtal.rate = xtal;
-       clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
+       clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
 
        clk_mpll.rate = fclk;
        clk_h.rate = hclk;
This page took 0.047219 seconds and 5 git commands to generate.