clk: qcom: Add handoff support for smd-rpm and voter rpm clocks
Some smd-rpm and voter rpm clocks are critical for system booting and should not be gated until a unused clock tree late_init level. So add support for handoff functionality for system critical rpm clocks by using CLK_ENABLE_HAND_OFF flag. Change-Id: I9f9674a25fc5f7a2bc9b5672b00716b82223b06b Signed-off-by: Amit Nischal <anischal@codeaurora.org>
This commit is contained in:
parent
83dbf65a2d
commit
5d81681e1e
3 changed files with 41 additions and 0 deletions
|
@ -55,6 +55,7 @@
|
||||||
.hw.init = &(struct clk_init_data){ \
|
.hw.init = &(struct clk_init_data){ \
|
||||||
.ops = &clk_smd_rpm_ops, \
|
.ops = &clk_smd_rpm_ops, \
|
||||||
.name = #_name, \
|
.name = #_name, \
|
||||||
|
.flags = CLK_ENABLE_HAND_OFF, \
|
||||||
.parent_names = (const char *[]){ "xo_board" }, \
|
.parent_names = (const char *[]){ "xo_board" }, \
|
||||||
.num_parents = 1, \
|
.num_parents = 1, \
|
||||||
}, \
|
}, \
|
||||||
|
@ -72,6 +73,7 @@
|
||||||
.hw.init = &(struct clk_init_data){ \
|
.hw.init = &(struct clk_init_data){ \
|
||||||
.ops = &clk_smd_rpm_ops, \
|
.ops = &clk_smd_rpm_ops, \
|
||||||
.name = #_active, \
|
.name = #_active, \
|
||||||
|
.flags = CLK_ENABLE_HAND_OFF, \
|
||||||
.parent_names = (const char *[]){ "xo_board" }, \
|
.parent_names = (const char *[]){ "xo_board" }, \
|
||||||
.num_parents = 1, \
|
.num_parents = 1, \
|
||||||
}, \
|
}, \
|
||||||
|
@ -95,6 +97,7 @@
|
||||||
.hw.init = &(struct clk_init_data){ \
|
.hw.init = &(struct clk_init_data){ \
|
||||||
.ops = &clk_smd_rpm_branch_ops, \
|
.ops = &clk_smd_rpm_branch_ops, \
|
||||||
.name = #_name, \
|
.name = #_name, \
|
||||||
|
.flags = CLK_ENABLE_HAND_OFF, \
|
||||||
.parent_names = (const char *[]){ "xo_board" }, \
|
.parent_names = (const char *[]){ "xo_board" }, \
|
||||||
.num_parents = 1, \
|
.num_parents = 1, \
|
||||||
}, \
|
}, \
|
||||||
|
@ -113,6 +116,7 @@
|
||||||
.hw.init = &(struct clk_init_data){ \
|
.hw.init = &(struct clk_init_data){ \
|
||||||
.ops = &clk_smd_rpm_branch_ops, \
|
.ops = &clk_smd_rpm_branch_ops, \
|
||||||
.name = #_active, \
|
.name = #_active, \
|
||||||
|
.flags = CLK_ENABLE_HAND_OFF, \
|
||||||
.parent_names = (const char *[]){ "xo_board" }, \
|
.parent_names = (const char *[]){ "xo_board" }, \
|
||||||
.num_parents = 1, \
|
.num_parents = 1, \
|
||||||
}, \
|
}, \
|
||||||
|
@ -177,6 +181,8 @@ struct rpm_smd_clk_desc {
|
||||||
|
|
||||||
static DEFINE_MUTEX(rpm_smd_clk_lock);
|
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)
|
static int clk_smd_rpm_handoff(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -198,6 +204,8 @@ static int clk_smd_rpm_handoff(struct clk_hw *hw)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = clk_smd_rpm_prepare(hw);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,12 +470,20 @@ static int clk_vote_bimc(struct clk_hw *hw, uint32_t rate)
|
||||||
return ret;
|
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 = {
|
static const struct clk_ops clk_smd_rpm_ops = {
|
||||||
.prepare = clk_smd_rpm_prepare,
|
.prepare = clk_smd_rpm_prepare,
|
||||||
.unprepare = clk_smd_rpm_unprepare,
|
.unprepare = clk_smd_rpm_unprepare,
|
||||||
.set_rate = clk_smd_rpm_set_rate,
|
.set_rate = clk_smd_rpm_set_rate,
|
||||||
.round_rate = clk_smd_rpm_round_rate,
|
.round_rate = clk_smd_rpm_round_rate,
|
||||||
.recalc_rate = clk_smd_rpm_recalc_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 = {
|
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,
|
.unprepare = clk_smd_rpm_unprepare,
|
||||||
.round_rate = clk_smd_rpm_round_rate,
|
.round_rate = clk_smd_rpm_round_rate,
|
||||||
.recalc_rate = clk_smd_rpm_recalc_rate,
|
.recalc_rate = clk_smd_rpm_recalc_rate,
|
||||||
|
.is_enabled = clk_smd_rpm_is_enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* msm8916 */
|
/* msm8916 */
|
||||||
|
@ -817,6 +834,17 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
|
||||||
goto err;
|
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();
|
ret = clk_smd_rpm_enable_scaling();
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -123,6 +123,16 @@ static unsigned long voter_clk_recalc_rate(struct clk_hw *hw,
|
||||||
return v->rate;
|
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 = {
|
struct clk_ops clk_ops_voter = {
|
||||||
.prepare = voter_clk_prepare,
|
.prepare = voter_clk_prepare,
|
||||||
.unprepare = voter_clk_unprepare,
|
.unprepare = voter_clk_unprepare,
|
||||||
|
|
|
@ -36,6 +36,7 @@ extern struct clk_ops clk_ops_voter;
|
||||||
.hw.init = &(struct clk_init_data){ \
|
.hw.init = &(struct clk_init_data){ \
|
||||||
.ops = &clk_ops_voter, \
|
.ops = &clk_ops_voter, \
|
||||||
.name = #clk_name, \
|
.name = #clk_name, \
|
||||||
|
.flags = CLK_ENABLE_HAND_OFF, \
|
||||||
.parent_names = (const char *[]){ #_parent_name }, \
|
.parent_names = (const char *[]){ #_parent_name }, \
|
||||||
.num_parents = 1, \
|
.num_parents = 1, \
|
||||||
}, \
|
}, \
|
||||||
|
@ -47,4 +48,6 @@ extern struct clk_ops clk_ops_voter;
|
||||||
#define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent_name) \
|
#define DEFINE_CLK_BRANCH_VOTER(clk_name, _parent_name) \
|
||||||
__DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1)
|
__DEFINE_CLK_VOTER(clk_name, _parent_name, 1000, 1)
|
||||||
|
|
||||||
|
int voter_clk_handoff(struct clk_hw *hw);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue