summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2010-11-08 16:30:11 -0800
committerColin Cross <ccross@android.com>2010-11-09 15:03:26 -0800
commitf58886c359db3c5056fea2d1a41d297f19e9f585 (patch)
treed6f298e88f07b72284d19094d7c3b9fd737244f1
parent5dd546a46322680abadc6c9dd091a215b4293f1e (diff)
ARM: tegra: dvfs: Fix locking on external dvfs calls
Change-Id: I9e3a3cc8c6c4424d7f7ded22d886d51f715ec5d5 Signed-off-by: Colin Cross <ccross@android.com>
-rw-r--r--arch/arm/mach-tegra/clock.c35
-rw-r--r--arch/arm/mach-tegra/clock.h1
-rw-r--r--arch/arm/mach-tegra/dvfs.c3
3 files changed, 28 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 34c2c29fa760..ad5f483af7fc 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -207,6 +207,22 @@ void clk_set_cansleep(struct clk *c)
mutex_unlock(&clock_list_lock);
}
+int tegra_dvfs_set_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long flags;
+ int ret;
+
+ if (!clk_is_dvfs(c))
+ return -EINVAL;
+
+ clk_lock_save(c, flags);
+ ret = tegra_dvfs_set_rate_locked(c, rate);
+ clk_unlock_restore(c, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(tegra_dvfs_set_rate);
+
int clk_reparent(struct clk *c, struct clk *parent)
{
c->parent = parent;
@@ -244,7 +260,7 @@ int clk_enable(struct clk *c)
clk_lock_save(c, flags);
if (clk_is_auto_dvfs(c)) {
- ret = tegra_dvfs_set_rate(c, clk_get_rate_locked(c));
+ ret = tegra_dvfs_set_rate_locked(c, clk_get_rate_locked(c));
if (ret)
goto out;
}
@@ -297,7 +313,7 @@ void clk_disable(struct clk *c)
c->refcnt--;
if (clk_is_auto_dvfs(c) && c->refcnt == 0)
- tegra_dvfs_set_rate(c, 0);
+ tegra_dvfs_set_rate_locked(c, 0);
clk_unlock_restore(c, flags);
}
@@ -322,7 +338,7 @@ int clk_set_parent(struct clk *c, struct clk *parent)
if (clk_is_auto_dvfs(c) && c->refcnt > 0 &&
(!c->parent || new_rate > old_rate)) {
- ret = tegra_dvfs_set_rate(c, new_rate);
+ ret = tegra_dvfs_set_rate_locked(c, new_rate);
if (ret)
goto out;
}
@@ -333,7 +349,7 @@ int clk_set_parent(struct clk *c, struct clk *parent)
if (clk_is_auto_dvfs(c) && c->refcnt > 0 &&
new_rate < old_rate)
- ret = tegra_dvfs_set_rate(c, new_rate);
+ ret = tegra_dvfs_set_rate_locked(c, new_rate);
out:
clk_unlock_restore(c, flags);
@@ -366,7 +382,7 @@ int clk_set_rate(struct clk *c, unsigned long rate)
rate = c->max_rate;
if (clk_is_auto_dvfs(c) && rate > old_rate && c->refcnt > 0) {
- ret = tegra_dvfs_set_rate(c, rate);
+ ret = tegra_dvfs_set_rate_locked(c, rate);
if (ret)
goto out;
}
@@ -376,7 +392,7 @@ int clk_set_rate(struct clk *c, unsigned long rate)
goto out;
if (clk_is_auto_dvfs(c) && rate < old_rate && c->refcnt > 0)
- ret = tegra_dvfs_set_rate(c, rate);
+ ret = tegra_dvfs_set_rate_locked(c, rate);
out:
clk_unlock_restore(c, flags);
@@ -527,11 +543,12 @@ void __init tegra_clk_set_dvfs_rates(void)
clk_lock_save(c, flags);
if (clk_is_auto_dvfs(c)) {
if (c->refcnt > 0)
- tegra_dvfs_set_rate(c, clk_get_rate_locked(c));
+ tegra_dvfs_set_rate_locked(c,
+ clk_get_rate_locked(c));
else
- tegra_dvfs_set_rate(c, 0);
+ tegra_dvfs_set_rate_locked(c, 0);
} else if (clk_is_dvfs(c)) {
- tegra_dvfs_set_rate(c, c->dvfs_rate);
+ tegra_dvfs_set_rate_locked(c, c->dvfs_rate);
}
clk_unlock_restore(c, flags);
}
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 0bcf475b3c82..083815487c17 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -165,5 +165,6 @@ void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
void tegra_clk_set_dvfs_rates(void);
void clk_set_cansleep(struct clk *c);
unsigned long clk_get_rate_locked(struct clk *c);
+int tegra_dvfs_set_rate_locked(struct clk *c, unsigned long rate);
#endif
diff --git a/arch/arm/mach-tegra/dvfs.c b/arch/arm/mach-tegra/dvfs.c
index d29315aed0dc..82a10f80696f 100644
--- a/arch/arm/mach-tegra/dvfs.c
+++ b/arch/arm/mach-tegra/dvfs.c
@@ -166,7 +166,7 @@ __tegra_dvfs_set_rate(struct clk *c, struct dvfs *d, unsigned long rate)
return ret;
}
-int tegra_dvfs_set_rate(struct clk *c, unsigned long rate)
+int tegra_dvfs_set_rate_locked(struct clk *c, unsigned long rate)
{
struct dvfs *d;
int ret = 0;
@@ -192,7 +192,6 @@ int tegra_dvfs_set_rate(struct clk *c, unsigned long rate)
return 0;
}
-EXPORT_SYMBOL(tegra_dvfs_set_rate);
/* May only be called during clock init, does not take any locks on clock c. */
int __init tegra_enable_dvfs_on_clk(struct clk *c, struct dvfs *d)