msm: clock: Clean up handoff function return values
The intended interpretation of handoff function return value was for 1 or
true to indicate that a handoff of a running clock had been successfully
performed, and 0 or false to indicate that it had not (either because the
clock was off or the rate was invalid).
Some handoff functions added later, however, used the value of 0 to mean
something else: that the handoff of some state was successful, but the
enabled/disabled state of the clock was not checked.
The vague definitions for the return codes of these functions make
it difficult to understand their intended behaviour. Address this by
using an enum of return codes so that their intentions are obvious.
Also update the functions that did not check enabled/disabled state
to do so and return meaningful values.
Change-Id: Iebf4c9e4b358379f7f048a720888b299dc9ee8e5
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 417b388..02706e0 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -2866,16 +2866,22 @@
return -ENXIO;
}
-static int pix_rdi_clk_handoff(struct clk *c)
+static enum handoff pix_rdi_clk_handoff(struct clk *c)
{
u32 reg;
struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+ enum handoff ret;
+
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return ret;
reg = readl_relaxed(clk->s_reg);
clk->cur_rate = reg & clk->s_mask ? 1 : 0;
reg = readl_relaxed(clk->s2_reg);
clk->cur_rate = reg & clk->s2_mask ? 2 : clk->cur_rate;
- return 0;
+
+ return HANDOFF_ENABLED_CLK;
}
static struct clk_ops clk_ops_pix_rdi_8960 = {
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index 3546ce0..acda059 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -567,34 +567,36 @@
}
/* Disable hw clock gating if not set at boot */
-static void branch_handoff(struct branch *clk, struct clk *c)
+enum handoff branch_handoff(struct branch *clk, struct clk *c)
{
if (!branch_in_hwcg_mode(clk)) {
clk->hwcg_mask = 0;
c->flags &= ~CLKFLAG_HWCG;
+ if (readl_relaxed(clk->ctl_reg) & clk->en_mask)
+ return HANDOFF_ENABLED_CLK;
} else {
c->flags |= CLKFLAG_HWCG;
}
+ return HANDOFF_DISABLED_CLK;
}
-int branch_clk_handoff(struct clk *c)
+enum handoff branch_clk_handoff(struct clk *c)
{
struct branch_clk *clk = to_branch_clk(c);
- branch_handoff(&clk->b, &clk->c);
- return 0;
+ return branch_handoff(&clk->b, &clk->c);
}
-int rcg_clk_handoff(struct clk *c)
+enum handoff rcg_clk_handoff(struct clk *c)
{
struct rcg_clk *clk = to_rcg_clk(c);
uint32_t ctl_val, ns_val, md_val, ns_mask;
struct clk_freq_tbl *freq;
-
- branch_handoff(&clk->b, &clk->c);
+ enum handoff ret;
ctl_val = readl_relaxed(clk->b.ctl_reg);
- if (!(ctl_val & clk->root_en_mask))
- return 0;
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return HANDOFF_DISABLED_CLK;
if (clk->bank_info) {
const struct bank_masks *bank_masks = clk->bank_info;
@@ -611,7 +613,8 @@
ns_mask = clk->ns_mask;
md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
}
-
+ if (!ns_mask)
+ return HANDOFF_UNKNOWN_RATE;
ns_val = readl_relaxed(clk->ns_reg) & ns_mask;
for (freq = clk->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
if ((freq->ns_val & ns_mask) == ns_val &&
@@ -621,12 +624,12 @@
}
}
if (freq->freq_hz == FREQ_END)
- return 0;
+ return HANDOFF_UNKNOWN_RATE;
clk->current_freq = freq;
c->rate = freq->freq_hz;
- return 1;
+ return HANDOFF_ENABLED_CLK;
}
int pll_vote_clk_enable(struct clk *clk)
@@ -1058,12 +1061,15 @@
return n > clk->max_div ? -ENXIO : n;
}
-static int cdiv_clk_handoff(struct clk *c)
+static enum handoff cdiv_clk_handoff(struct clk *c)
{
struct cdiv_clk *clk = to_cdiv_clk(c);
+ enum handoff ret;
u32 reg_val;
- branch_handoff(&clk->b, &clk->c);
+ ret = branch_handoff(&clk->b, &clk->c);
+ if (ret == HANDOFF_DISABLED_CLK)
+ return ret;
reg_val = readl_relaxed(clk->ns_reg);
if (reg_val & clk->ext_mask) {
@@ -1073,7 +1079,7 @@
clk->cur_div = (reg_val & (clk->max_div - 1)) + 1;
}
- return 0;
+ return HANDOFF_ENABLED_CLK;
}
static void cdiv_clk_enable_hwcg(struct clk *c)
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 44e86b1..48049ec 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -171,7 +171,8 @@
int branch_reset(struct branch *b, enum clk_reset_action action);
void __branch_clk_enable_reg(const struct branch *clk, const char *name);
u32 __branch_clk_disable_reg(const struct branch *clk, const char *name);
-int branch_clk_handoff(struct clk *c);
+enum handoff branch_clk_handoff(struct clk *c);
+enum handoff branch_handoff(struct branch *clk, struct clk *c);
int branch_clk_set_flags(struct clk *clk, unsigned flags);
/*
@@ -211,7 +212,7 @@
int rcg_clk_is_enabled(struct clk *clk);
long rcg_clk_round_rate(struct clk *clk, unsigned long rate);
struct clk *rcg_clk_get_parent(struct clk *c);
-int rcg_clk_handoff(struct clk *c);
+enum handoff rcg_clk_handoff(struct clk *c);
int rcg_clk_reset(struct clk *clk, enum clk_reset_action action);
void rcg_clk_enable_hwcg(struct clk *clk);
void rcg_clk_disable_hwcg(struct clk *clk);
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index b5b6ca7..68c390a 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -156,7 +156,7 @@
return true;
}
-static int pll_clk_handoff(struct clk *clk)
+static enum handoff pll_clk_handoff(struct clk *clk)
{
struct pll_shared_clk *pll = to_pll_shared_clk(clk);
unsigned int pll_lval;
@@ -184,7 +184,7 @@
BUG();
}
- return 0;
+ return HANDOFF_ENABLED_CLK;
}
struct clk_ops clk_pll_ops = {
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 1776c12..cbb86a7 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -412,7 +412,7 @@
struct clk *parent = clk_get_parent(clk);
clk_set_parent(clk, parent);
if (clk->ops->handoff && !(clk->flags & CLKFLAG_HANDOFF_RATE)) {
- if (clk->ops->handoff(clk)) {
+ if (clk->ops->handoff(clk) == HANDOFF_ENABLED_CLK) {
clk->flags |= CLKFLAG_HANDOFF_RATE;
clk_prepare_enable(clk);
}
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index a70dbd1..60be654 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -63,6 +63,12 @@
.lock = __SPIN_LOCK_UNLOCKED(lock) \
}
+enum handoff {
+ HANDOFF_ENABLED_CLK,
+ HANDOFF_DISABLED_CLK,
+ HANDOFF_UNKNOWN_RATE,
+};
+
struct clk_ops {
int (*prepare)(struct clk *clk);
int (*enable)(struct clk *clk);
@@ -72,7 +78,7 @@
void (*enable_hwcg)(struct clk *clk);
void (*disable_hwcg)(struct clk *clk);
int (*in_hwcg_mode)(struct clk *clk);
- int (*handoff)(struct clk *clk);
+ enum handoff (*handoff)(struct clk *clk);
int (*reset)(struct clk *clk, enum clk_reset_action action);
int (*set_rate)(struct clk *clk, unsigned long rate);
int (*set_max_rate)(struct clk *clk, unsigned long rate);