summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-01-03 08:43:37 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-03 08:43:37 -0800
commitf30bbe04d2ba222cb30366e35cf569fa144f983f (patch)
treee138a2f903c4704943b7805d6702fe8a5ec934f2
parentc27d8f3edb8c725560cd4e0d02e6ea6f7b66a6c7 (diff)
parent5d81681e1efd7a80f897b30216a3db15674e5684 (diff)
Merge "clk: qcom: Add handoff support for smd-rpm and voter rpm clocks"
-rw-r--r--drivers/clk/qcom/clk-smd-rpm.c28
-rw-r--r--drivers/clk/qcom/clk-voter.c10
-rw-r--r--drivers/clk/qcom/clk-voter.h3
3 files changed, 41 insertions, 0 deletions
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c
index 349af277291d..9015d505f4dc 100644
--- a/drivers/clk/qcom/clk-smd-rpm.c
+++ b/drivers/clk/qcom/clk-smd-rpm.c
@@ -55,6 +55,7 @@
.hw.init = &(struct clk_init_data){ \
.ops = &clk_smd_rpm_ops, \
.name = #_name, \
+ .flags = CLK_ENABLE_HAND_OFF, \
.parent_names = (const char *[]){ "xo_board" }, \
.num_parents = 1, \
}, \
@@ -72,6 +73,7 @@
.hw.init = &(struct clk_init_data){ \
.ops = &clk_smd_rpm_ops, \
.name = #_active, \
+ .flags = CLK_ENABLE_HAND_OFF, \
.parent_names = (const char *[]){ "xo_board" }, \
.num_parents = 1, \
}, \
@@ -95,6 +97,7 @@
.hw.init = &(struct clk_init_data){ \
.ops = &clk_smd_rpm_branch_ops, \
.name = #_name, \
+ .flags = CLK_ENABLE_HAND_OFF, \
.parent_names = (const char *[]){ "xo_board" }, \
.num_parents = 1, \
}, \
@@ -113,6 +116,7 @@
.hw.init = &(struct clk_init_data){ \
.ops = &clk_smd_rpm_branch_ops, \
.name = #_active, \
+ .flags = CLK_ENABLE_HAND_OFF, \
.parent_names = (const char *[]){ "xo_board" }, \
.num_parents = 1, \
}, \
@@ -177,6 +181,8 @@ struct rpm_smd_clk_desc {
static DEFINE_MUTEX(rpm_smd_clk_lock);
+static int clk_smd_rpm_prepare(struct clk_hw *hw);
+
static int clk_smd_rpm_handoff(struct clk_hw *hw)
{
int ret = 0;
@@ -198,6 +204,8 @@ static int clk_smd_rpm_handoff(struct clk_hw *hw)
if (ret)
return ret;
+ ret = clk_smd_rpm_prepare(hw);
+
return ret;
}
@@ -462,12 +470,20 @@ static int clk_vote_bimc(struct clk_hw *hw, uint32_t rate)
return ret;
}
+static int clk_smd_rpm_is_enabled(struct clk_hw *hw)
+{
+ struct clk_smd_rpm *r = to_clk_smd_rpm(hw);
+
+ return r->enabled;
+}
+
static const struct clk_ops clk_smd_rpm_ops = {
.prepare = clk_smd_rpm_prepare,
.unprepare = clk_smd_rpm_unprepare,
.set_rate = clk_smd_rpm_set_rate,
.round_rate = clk_smd_rpm_round_rate,
.recalc_rate = clk_smd_rpm_recalc_rate,
+ .is_enabled = clk_smd_rpm_is_enabled,
};
static const struct clk_ops clk_smd_rpm_branch_ops = {
@@ -475,6 +491,7 @@ static const struct clk_ops clk_smd_rpm_branch_ops = {
.unprepare = clk_smd_rpm_unprepare,
.round_rate = clk_smd_rpm_round_rate,
.recalc_rate = clk_smd_rpm_recalc_rate,
+ .is_enabled = clk_smd_rpm_is_enabled,
};
/* msm8916 */
@@ -817,6 +834,17 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
goto err;
}
+ for (i = (desc->num_rpm_clks + 1); i < num_clks; i++) {
+ if (!hw_clks[i]) {
+ clks[i] = ERR_PTR(-ENOENT);
+ continue;
+ }
+
+ ret = voter_clk_handoff(hw_clks[i]);
+ if (ret)
+ goto err;
+ }
+
ret = clk_smd_rpm_enable_scaling();
if (ret)
goto err;
diff --git a/drivers/clk/qcom/clk-voter.c b/drivers/clk/qcom/clk-voter.c
index d3409b9e6b64..60e319620e1b 100644
--- a/drivers/clk/qcom/clk-voter.c
+++ b/drivers/clk/qcom/clk-voter.c
@@ -123,6 +123,16 @@ static unsigned long voter_clk_recalc_rate(struct clk_hw *hw,
return v->rate;
}
+int voter_clk_handoff(struct clk_hw *hw)
+{
+ struct clk_voter *v = to_clk_voter(hw);
+
+ v->enabled = true;
+
+ return 0;
+}
+EXPORT_SYMBOL(voter_clk_handoff);
+
struct clk_ops clk_ops_voter = {
.prepare = voter_clk_prepare,
.unprepare = voter_clk_unprepare,
diff --git a/drivers/clk/qcom/clk-voter.h b/drivers/clk/qcom/clk-voter.h
index 27092ae7d131..abc26cd94cd5 100644
--- a/drivers/clk/qcom/clk-voter.h
+++ b/drivers/clk/qcom/clk-voter.h
@@ -36,6 +36,7 @@ extern struct clk_ops clk_ops_voter;
.hw.init = &(struct clk_init_data){ \
.ops = &clk_ops_voter, \
.name = #clk_name, \
+ .flags = CLK_ENABLE_HAND_OFF, \
.parent_names = (const char *[]){ #_parent_name }, \
.num_parents = 1, \
}, \
@@ -47,4 +48,6 @@ extern struct clk_ops clk_ops_voter;
#define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent_name) \
__DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1)
+int voter_clk_handoff(struct clk_hw *hw);
+
#endif