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);