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)