msm: clock: Return error upon invalid call to clk_set_rate.
Calls to clk_set_rate should only change the voltage vote if the clock
is prepared. However, they need to check if the rate is valid even if
the clock is not prepared.
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
(cherry picked from commit c009d9efe966f1f2ac300d43895bb448a9d27cc0)
Signed-off-by: Dhivya Subramanian <dthiru@codeaurora.org>
(cherry picked from commit 8b5d9d1b3b75cf42df5cf1faeda029ebfbdd308e)
Change-Id: I3a80401dcf76314441ad7624c69433c0ea1d1efe
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index a0367b0..6a3a282 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -135,6 +135,18 @@
unvote_vdd_level(clk->vdd_class, level);
}
+/* Returns true if the rate is valid without voting for it */
+static bool is_rate_valid(struct clk *clk, unsigned long rate)
+{
+ int level;
+
+ if (!clk->vdd_class)
+ return true;
+
+ level = find_vdd_level(clk, rate);
+ return level >= 0;
+}
+
int clk_prepare(struct clk *clk)
{
int ret = 0;
@@ -337,14 +349,16 @@
/* Enforce vdd requirements for target frequency. */
rc = vote_rate_vdd(clk, rate);
if (rc)
- goto err_vote_vdd;
+ goto out;
rc = clk->ops->set_rate(clk, rate);
if (rc)
goto err_set_rate;
/* Release vdd requirements for starting frequency. */
unvote_rate_vdd(clk, start_rate);
- } else {
+ } else if (is_rate_valid(clk, rate)) {
rc = clk->ops->set_rate(clk, rate);
+ } else {
+ rc = -EINVAL;
}
if (!rc)
@@ -355,7 +369,6 @@
err_set_rate:
unvote_rate_vdd(clk, rate);
-err_vote_vdd:
goto out;
}
EXPORT_SYMBOL(clk_set_rate);