From: Colin Cross Date: Tue, 9 Nov 2010 00:30:11 +0000 (-0800) Subject: ARM: tegra: dvfs: Fix locking on external dvfs calls X-Git-Tag: firefly_0821_release~9833^2~117^2~2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f58886c359db3c5056fea2d1a41d297f19e9f585;p=firefly-linux-kernel-4.4.55.git ARM: tegra: dvfs: Fix locking on external dvfs calls Change-Id: I9e3a3cc8c6c4424d7f7ded22d886d51f715ec5d5 Signed-off-by: Colin Cross --- 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)