diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index da02ab499bff..4589a3b6cec6 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -24,6 +24,7 @@ struct freq_tbl { u16 m; u16 n; unsigned long src_freq; +#define FIXED_FREQ_SRC 0 }; /** diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 6d12ddb3e245..eb8101a69f5e 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -232,9 +232,10 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f, struct clk_rate_request *req) { unsigned long clk_flags, rate = req->rate; + struct clk_rate_request parent_req = { }; struct clk_hw *p; struct clk_rcg2 *rcg = to_clk_rcg2(hw); - int index; + int index, ret = 0; f = qcom_find_freq(f, rate); if (!f) @@ -265,6 +266,21 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, req->best_parent_rate = rate; req->rate = f->freq; + if (f->src_freq != FIXED_FREQ_SRC) { + rate = parent_req.rate = f->src_freq; + parent_req.best_parent_hw = p; + ret = __clk_determine_rate(p, &parent_req); + if (ret) + return ret; + + ret = clk_set_rate(p->clk, parent_req.rate); + if (ret) { + pr_err("Failed set rate(%lu) on parent for non-fixed source\n", + parent_req.rate); + return ret; + } + } + return 0; }