msm: clock-rpm: Abstract out calls to RPM APIs.

The RPM communication driver is changing its underlying
transport layer for upcoming chipsets. To support
the current transport layer and future ones, abstract
out the calls to the RPM APIs into helper functions.

Change-Id: I7bd2706dd7bb69812b3baac12eca7893aca749ab
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index d21a7c8..616dcdc 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -18,13 +18,64 @@
 #include "clock.h"
 #include "clock-rpm.h"
 
+#define __clk_rpmrs_set_rate(r, value, ctx, noirq) \
+	((r)->rpmrs_data->set_rate_fn((r), (value), (ctx), (noirq)))
+
+#define clk_rpmrs_set_rate_sleep(r, value) \
+	    __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 0)
+
+#define clk_rpmrs_set_rate_sleep_noirq(r, value) \
+	    __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_sleep_id, 1)
+
+#define clk_rpmrs_set_rate_active(r, value) \
+	   __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 0)
+
+#define clk_rpmrs_set_rate_active_noirq(r, value) \
+	   __clk_rpmrs_set_rate((r), (value), (r)->rpmrs_data->ctx_active_id, 1)
+
+static int clk_rpmrs_set_rate(struct rpm_clk *r, uint32_t value,
+			   uint32_t context, int noirq)
+{
+	struct msm_rpm_iv_pair iv = {
+		.id = r->rpm_clk_id,
+		.value = value,
+	};
+	if (noirq)
+		return msm_rpmrs_set_noirq(context, &iv, 1);
+	else
+		return msm_rpmrs_set(context, &iv, 1);
+}
+
+static int clk_rpmrs_get_rate(struct rpm_clk *r)
+{
+	int rc;
+	struct msm_rpm_iv_pair iv = { .id = r->rpm_status_id, };
+	rc = msm_rpm_get_status(&iv, 1);
+	return (rc < 0) ? rc : iv.value * 1000;
+}
+
+struct clk_rpmrs_data {
+	int (*set_rate_fn)(struct rpm_clk *r, uint32_t value,
+				uint32_t context, int noirq);
+	int (*get_rate_fn)(struct rpm_clk *r);
+	int ctx_active_id;
+	int ctx_sleep_id;
+};
+
+struct clk_rpmrs_data clk_rpmrs_data = {
+	.set_rate_fn = clk_rpmrs_set_rate,
+	.get_rate_fn = clk_rpmrs_get_rate,
+	.ctx_active_id = MSM_RPM_CTX_SET_0,
+	.ctx_sleep_id = MSM_RPM_CTX_SET_SLEEP,
+};
+
 static DEFINE_SPINLOCK(rpm_clock_lock);
 
 static int rpm_clk_enable(struct clk *clk)
 {
 	unsigned long flags;
 	struct rpm_clk *r = to_rpm_clk(clk);
-	struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
+	uint32_t value;
 	int rc = 0;
 	unsigned long this_khz, this_sleep_khz;
 	unsigned long peer_khz = 0, peer_sleep_khz = 0;
@@ -45,21 +96,23 @@
 		peer_sleep_khz = peer->last_set_sleep_khz;
 	}
 
-	iv.value = max(this_khz, peer_khz);
+	value = max(this_khz, peer_khz);
 	if (r->branch)
-		iv.value = !!iv.value;
+		value = !!value;
 
-	rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+	rc = clk_rpmrs_set_rate_active_noirq(r, value);
 	if (rc)
 		goto out;
 
-	iv.value = max(this_sleep_khz, peer_sleep_khz);
+	value = max(this_sleep_khz, peer_sleep_khz);
 	if (r->branch)
-		iv.value = !!iv.value;
-	rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = !!value;
+
+	rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	if (rc) {
-		iv.value = peer_khz;
-		msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		/* Undo the active set vote and restore it to peer_khz */
+		value = peer_khz;
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 	}
 
 out:
@@ -79,7 +132,7 @@
 	spin_lock_irqsave(&rpm_clock_lock, flags);
 
 	if (r->last_set_khz) {
-		struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
+		uint32_t value;
 		struct rpm_clk *peer = r->peer;
 		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 		int rc;
@@ -90,13 +143,13 @@
 			peer_sleep_khz = peer->last_set_sleep_khz;
 		}
 
-		iv.value = r->branch ? !!peer_khz : peer_khz;
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		value = r->branch ? !!peer_khz : peer_khz;
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 		if (rc)
 			goto out;
 
-		iv.value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
+		rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	}
 	r->enabled = false;
 out:
@@ -124,25 +177,23 @@
 		this_sleep_khz = this_khz;
 
 	if (r->enabled) {
-		struct msm_rpm_iv_pair iv;
+		uint32_t value;
 		struct rpm_clk *peer = r->peer;
 		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 
-		iv.id = r->rpm_clk_id;
-
 		/* Take peer clock's rate into account only if it's enabled. */
 		if (peer->enabled) {
 			peer_khz = peer->last_set_khz;
 			peer_sleep_khz = peer->last_set_sleep_khz;
 		}
 
-		iv.value = max(this_khz, peer_khz);
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
+		value = max(this_khz, peer_khz);
+		rc = clk_rpmrs_set_rate_active_noirq(r, value);
 		if (rc)
 			goto out;
 
-		iv.value = max(this_sleep_khz, peer_sleep_khz);
-		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
+		value = max(this_sleep_khz, peer_sleep_khz);
+		rc = clk_rpmrs_set_rate_sleep_noirq(r, value);
 	}
 	if (!rc) {
 		r->last_set_khz = this_khz;
@@ -158,13 +209,10 @@
 static unsigned long rpm_clk_get_rate(struct clk *clk)
 {
 	struct rpm_clk *r = to_rpm_clk(clk);
-	struct msm_rpm_iv_pair iv = { r->rpm_status_id };
-	int rc;
-
-	rc  = msm_rpm_get_status(&iv, 1);
-	if (rc < 0)
-		return rc;
-	return iv.value * 1000;
+	if (r->rpmrs_data->get_rate_fn)
+		return r->rpmrs_data->get_rate_fn(r);
+	else
+		return 0;
 }
 
 static int rpm_clk_is_enabled(struct clk *clk)
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index b0d5693..35b36ae 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -17,6 +17,7 @@
 #include <mach/rpm.h>
 
 struct clk_ops;
+struct clk_rpmrs_data;
 extern struct clk_ops clk_ops_rpm;
 extern struct clk_ops clk_ops_rpm_branch;
 
@@ -29,6 +30,7 @@
 	unsigned last_set_sleep_khz;
 	bool enabled;
 	bool branch; /* true: RPM only accepts 1 for ON and 0 for OFF */
+	struct clk_rpmrs_data *rpmrs_data;
 
 	struct rpm_clk *peer;
 	struct clk c;
@@ -39,12 +41,15 @@
 	return container_of(clk, struct rpm_clk, c);
 }
 
+extern struct clk_rpmrs_data clk_rpmrs_data;
+
 #define DEFINE_CLK_RPM(name, active, r_id, dep) \
 	static struct rpm_clk active; \
 	static struct rpm_clk name = { \
 		.rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
 		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
 		.peer = &active, \
+		.rpmrs_data = &clk_rpmrs_data,\
 		.c = { \
 			.ops = &clk_ops_rpm, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -58,6 +63,7 @@
 		.rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
 		.peer = &name, \
 		.active_only = true, \
+		.rpmrs_data = &clk_rpmrs_data,\
 		.c = { \
 			.ops = &clk_ops_rpm, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -76,6 +82,7 @@
 		.last_set_khz = ((r) / 1000), \
 		.last_set_sleep_khz = ((r) / 1000), \
 		.branch = true, \
+		.rpmrs_data = &clk_rpmrs_data,\
 		.c = { \
 			.ops = &clk_ops_rpm_branch, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \
@@ -92,6 +99,7 @@
 		.last_set_khz = ((r) / 1000), \
 		.active_only = true, \
 		.branch = true, \
+		.rpmrs_data = &clk_rpmrs_data,\
 		.c = { \
 			.ops = &clk_ops_rpm_branch, \
 			.flags = CLKFLAG_SKIP_AUTO_OFF, \