Re: [RFCv2 2/8] clk: imx8m-composite: Switch to determine_rate
From: Abel Vesa <hidden>
Date: 2019-06-28 08:45:31
Also in:
linux-clk, linux-pm
On 19-06-28 10:39:50, Leonard Crestez wrote:
quoted hunk ↗ jump to hunk
This allows consumers to use min_rate max_rate. Signed-off-by: Leonard Crestez <redacted> --- drivers/clk/imx/clk-composite-8m.c | 34 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-)diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 388bdb94f841..1be82ec08ecd 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c@@ -45,10 +45,12 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw, divider->flags, PCG_DIV_WIDTH); } static int imx8m_clk_composite_compute_dividers(unsigned long rate, unsigned long parent_rate, + unsigned long min_rate, + unsigned long max_rate,
You should pass on the req instead of min_rate and max_rate here.
quoted hunk ↗ jump to hunk
int *prediv, int *postdiv) { int div1, div2; int error = INT_MAX; int ret = -EINVAL;@@ -56,11 +58,17 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, *prediv = 1; *postdiv = 1; for (div1 = 1; div1 <= PCG_PREDIV_MAX; div1++) { for (div2 = 1; div2 <= PCG_DIV_MAX; div2++) { - int new_error = ((parent_rate / div1) / div2) - rate; + unsigned long new_rate; + int new_error; + + new_rate = ((parent_rate / div1) / div2); + if (new_rate < min_rate || new_rate > max_rate) + continue; + new_error = new_rate - rate; if (abs(new_error) < abs(error)) { *prediv = div1; *postdiv = div2; error = new_error;@@ -69,38 +77,40 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, } } return ret; } -static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int imx8m_clk_composite_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int prediv_value; int div_value; - imx8m_clk_composite_compute_dividers(rate, *prate, - &prediv_value, &div_value); - rate = DIV_ROUND_UP(*prate, prediv_value); + imx8m_clk_composite_compute_dividers(req->rate, req->best_parent_rate, + req->min_rate, req->max_rate, + &prediv_value, &div_value); - return DIV_ROUND_UP(rate, div_value); + req->rate = DIV_ROUND_UP(req->best_parent_rate, prediv_value); + req->rate = DIV_ROUND_UP(req->rate, div_value); + return 0; } static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long parent_rate) + unsigned long rate, + unsigned long parent_rate) { struct clk_divider *divider = to_clk_divider(hw); unsigned long flags = 0; int prediv_value; int div_value; int ret; u32 val; ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, - &prediv_value, &div_value); + 0, ULONG_MAX, + &prediv_value, &div_value); if (ret) return -EINVAL; spin_lock_irqsave(divider->lock, flags);@@ -117,11 +127,11 @@ static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, return ret; } static const struct clk_ops imx8m_clk_composite_divider_ops = { .recalc_rate = imx8m_clk_composite_divider_recalc_rate, - .round_rate = imx8m_clk_composite_divider_round_rate, + .determine_rate = imx8m_clk_composite_divider_determine_rate, .set_rate = imx8m_clk_composite_divider_set_rate, }; struct clk *imx8m_clk_composite_flags(const char *name, const char * const *parent_names,-- 2.17.1
_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel