Commit 93d199a1 authored by Roland Stigge's avatar Roland Stigge Committed by Olof Johansson

ARM: LPC32xx: clock.c: Fix mutex lock issues

This patch fixes the mutex issue in clock.c, as done in Kevin Wells' original
driver update:

In some cases, the clock drivers could grab a mutex twice in an improper
context. This patch changes the mutex mechanism to a simple irq lock/unlock
mechanism and removes un-needed locks from some functions.

(See also git.lpclinux.com)
Signed-off-by: default avatarRoland Stigge <stigge@antcom.de>
Tested-by: default avatarWolfram Sang <w.sang@pengutronix.de>
Acked-by: default avatarKevin Wells <kevin.wells@nxp.com>
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parent 9862048a
...@@ -97,9 +97,10 @@ ...@@ -97,9 +97,10 @@
#include "clock.h" #include "clock.h"
#include "common.h" #include "common.h"
static DEFINE_SPINLOCK(global_clkregs_lock);
static struct clk clk_armpll; static struct clk clk_armpll;
static struct clk clk_usbpll; static struct clk clk_usbpll;
static DEFINE_MUTEX(clkm_lock);
/* /*
* Post divider values for PLLs based on selected register value * Post divider values for PLLs based on selected register value
...@@ -891,16 +892,6 @@ static struct clk clk_lcd = { ...@@ -891,16 +892,6 @@ static struct clk clk_lcd = {
.enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
}; };
static inline void clk_lock(void)
{
mutex_lock(&clkm_lock);
}
static inline void clk_unlock(void)
{
mutex_unlock(&clkm_lock);
}
static void local_clk_disable(struct clk *clk) static void local_clk_disable(struct clk *clk)
{ {
/* Don't attempt to disable clock if it has no users */ /* Don't attempt to disable clock if it has no users */
...@@ -945,10 +936,11 @@ static int local_clk_enable(struct clk *clk) ...@@ -945,10 +936,11 @@ static int local_clk_enable(struct clk *clk)
int clk_enable(struct clk *clk) int clk_enable(struct clk *clk)
{ {
int ret; int ret;
unsigned long flags;
clk_lock(); spin_lock_irqsave(&global_clkregs_lock, flags);
ret = local_clk_enable(clk); ret = local_clk_enable(clk);
clk_unlock(); spin_unlock_irqrestore(&global_clkregs_lock, flags);
return ret; return ret;
} }
...@@ -959,9 +951,11 @@ EXPORT_SYMBOL(clk_enable); ...@@ -959,9 +951,11 @@ EXPORT_SYMBOL(clk_enable);
*/ */
void clk_disable(struct clk *clk) void clk_disable(struct clk *clk)
{ {
clk_lock(); unsigned long flags;
spin_lock_irqsave(&global_clkregs_lock, flags);
local_clk_disable(clk); local_clk_disable(clk);
clk_unlock(); spin_unlock_irqrestore(&global_clkregs_lock, flags);
} }
EXPORT_SYMBOL(clk_disable); EXPORT_SYMBOL(clk_disable);
...@@ -970,13 +964,7 @@ EXPORT_SYMBOL(clk_disable); ...@@ -970,13 +964,7 @@ EXPORT_SYMBOL(clk_disable);
*/ */
unsigned long clk_get_rate(struct clk *clk) unsigned long clk_get_rate(struct clk *clk)
{ {
unsigned long rate; return clk->get_rate(clk);
clk_lock();
rate = clk->get_rate(clk);
clk_unlock();
return rate;
} }
EXPORT_SYMBOL(clk_get_rate); EXPORT_SYMBOL(clk_get_rate);
...@@ -992,11 +980,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) ...@@ -992,11 +980,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
* the actual rate set as part of the peripheral dividers * the actual rate set as part of the peripheral dividers
* instead of high level clock control * instead of high level clock control
*/ */
if (clk->set_rate) { if (clk->set_rate)
clk_lock();
ret = clk->set_rate(clk, rate); ret = clk->set_rate(clk, rate);
clk_unlock();
}
return ret; return ret;
} }
...@@ -1007,15 +992,11 @@ EXPORT_SYMBOL(clk_set_rate); ...@@ -1007,15 +992,11 @@ EXPORT_SYMBOL(clk_set_rate);
*/ */
long clk_round_rate(struct clk *clk, unsigned long rate) long clk_round_rate(struct clk *clk, unsigned long rate)
{ {
clk_lock();
if (clk->round_rate) if (clk->round_rate)
rate = clk->round_rate(clk, rate); rate = clk->round_rate(clk, rate);
else else
rate = clk->get_rate(clk); rate = clk->get_rate(clk);
clk_unlock();
return rate; return rate;
} }
EXPORT_SYMBOL(clk_round_rate); EXPORT_SYMBOL(clk_round_rate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment