#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 */
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 &&
}
}
- mutex_unlock(&clocks_mutex);
+ spin_unlock(&clocks_lock);
return 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;
}
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);
}
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;
}
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;
}
/* 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;
}
/* 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;