clk: sunxi-ng: convert from divider_round_rate_parent() to divider_determine_rate()

The divider_round_rate_parent() function is now deprecated, so let's
migrate to divider_determine_rate() instead so that this deprecated API
can be removed. Also go ahead and convert all of the driver from round
rate type to determine rate that accepts a 'struct clk_rate_request' to
simplify the overall driver code.

Acked-by: Chen-Yu Tsai <wens@kernel.org>
Signed-off-by: Brian Masney <bmasney@redhat.com>
This commit is contained in:
Brian Masney 2026-01-08 16:16:20 -05:00
parent a641384bb0
commit 1c8d7af61b
6 changed files with 79 additions and 70 deletions

View File

@ -10,26 +10,25 @@
#include "ccu_gate.h" #include "ccu_gate.h"
#include "ccu_div.h" #include "ccu_div.h"
static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux,
struct clk_hw *parent, struct clk_rate_request *req,
unsigned long *parent_rate, void *data)
unsigned long rate,
void *data)
{ {
struct ccu_div *cd = data; struct ccu_div *cd = data;
int ret;
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= cd->fixed_post_div; req->rate *= cd->fixed_post_div;
rate = divider_round_rate_parent(&cd->common.hw, parent, ret = divider_determine_rate(&cd->common.hw, req, cd->div.table,
rate, parent_rate, cd->div.width, cd->div.flags);
cd->div.table, cd->div.width, if (ret)
cd->div.flags); return ret;
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= cd->fixed_post_div; req->rate /= cd->fixed_post_div;
return rate; return 0;
} }
static void ccu_div_disable(struct clk_hw *hw) static void ccu_div_disable(struct clk_hw *hw)
@ -82,7 +81,7 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
struct ccu_div *cd = hw_to_ccu_div(hw); struct ccu_div *cd = hw_to_ccu_div(hw);
return ccu_mux_helper_determine_rate(&cd->common, &cd->mux, return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
req, ccu_div_round_rate, cd); req, ccu_div_determine_rate_helper, cd);
} }
static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,

View File

@ -103,11 +103,9 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
return best_rate; return best_rate;
} }
static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, static int ccu_mp_determine_rate_helper(struct ccu_mux_internal *mux,
struct clk_hw *hw, struct clk_rate_request *req,
unsigned long *parent_rate, void *data)
unsigned long rate,
void *data)
{ {
struct ccu_mp *cmp = data; struct ccu_mp *cmp = data;
unsigned int max_m, max_p; unsigned int max_m, max_p;
@ -115,7 +113,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
bool shift = true; bool shift = true;
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= cmp->fixed_post_div; req->rate *= cmp->fixed_post_div;
if (cmp->common.features & CCU_FEATURE_DUAL_DIV) if (cmp->common.features & CCU_FEATURE_DUAL_DIV)
shift = false; shift = false;
@ -127,17 +125,19 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
max_p = cmp->p.max ?: 1 << cmp->p.width; max_p = cmp->p.max ?: 1 << cmp->p.width;
if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) {
rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, shift, req->rate = ccu_mp_find_best(req->best_parent_rate, req->rate,
&m, &p); max_m, max_p, shift, &m, &p);
} else { } else {
rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, req->rate = ccu_mp_find_best_with_parent_adj(req->best_parent_hw,
max_m, max_p, shift); &req->best_parent_rate,
req->rate, max_m, max_p,
shift);
} }
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= cmp->fixed_post_div; req->rate /= cmp->fixed_post_div;
return rate; return 0;
} }
static void ccu_mp_disable(struct clk_hw *hw) static void ccu_mp_disable(struct clk_hw *hw)
@ -201,7 +201,7 @@ static int ccu_mp_determine_rate(struct clk_hw *hw,
struct ccu_mp *cmp = hw_to_ccu_mp(hw); struct ccu_mp *cmp = hw_to_ccu_mp(hw);
return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux, return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux,
req, ccu_mp_round_rate, cmp); req, ccu_mp_determine_rate_helper, cmp);
} }
static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,

View File

@ -29,11 +29,9 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate,
mult->mult = _mult; mult->mult = _mult;
} }
static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, static int ccu_mult_determine_rate_helper(struct ccu_mux_internal *mux,
struct clk_hw *parent, struct clk_rate_request *req,
unsigned long *parent_rate, void *data)
unsigned long rate,
void *data)
{ {
struct ccu_mult *cm = data; struct ccu_mult *cm = data;
struct _ccu_mult _cm; struct _ccu_mult _cm;
@ -45,9 +43,11 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
else else
_cm.max = (1 << cm->mult.width) + cm->mult.offset - 1; _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
ccu_mult_find_best(*parent_rate, rate, &_cm); ccu_mult_find_best(req->best_parent_rate, req->rate, &_cm);
return *parent_rate * _cm.mult; req->rate = req->best_parent_rate * _cm.mult;
return 0;
} }
static void ccu_mult_disable(struct clk_hw *hw) static void ccu_mult_disable(struct clk_hw *hw)
@ -97,7 +97,7 @@ static int ccu_mult_determine_rate(struct clk_hw *hw,
struct ccu_mult *cm = hw_to_ccu_mult(hw); struct ccu_mult *cm = hw_to_ccu_mult(hw);
return ccu_mux_helper_determine_rate(&cm->common, &cm->mux, return ccu_mux_helper_determine_rate(&cm->common, &cm->mux,
req, ccu_mult_round_rate, cm); req, ccu_mult_determine_rate_helper, cm);
} }
static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,

View File

@ -79,41 +79,46 @@ static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
int ccu_mux_helper_determine_rate(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common,
struct ccu_mux_internal *cm, struct ccu_mux_internal *cm,
struct clk_rate_request *req, struct clk_rate_request *req,
unsigned long (*round)(struct ccu_mux_internal *, int (*round)(struct ccu_mux_internal *,
struct clk_hw *, struct clk_rate_request *,
unsigned long *, void *),
unsigned long,
void *),
void *data) void *data)
{ {
unsigned long best_parent_rate = 0, best_rate = 0; unsigned long best_parent_rate = 0, best_rate = 0;
struct clk_hw *best_parent, *hw = &common->hw; struct clk_hw *best_parent, *hw = &common->hw;
unsigned int i; unsigned int i;
int ret;
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
unsigned long adj_parent_rate; struct clk_rate_request adj_req = *req;
best_parent = clk_hw_get_parent(hw); best_parent = clk_hw_get_parent(hw);
best_parent_rate = clk_hw_get_rate(best_parent); best_parent_rate = clk_hw_get_rate(best_parent);
adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
best_parent_rate);
best_rate = round(cm, best_parent, &adj_parent_rate, adj_req.best_parent_hw = best_parent;
req->rate, data); adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
best_parent_rate);
ret = round(cm, &adj_req, data);
if (ret)
return ret;
best_rate = adj_req.rate;
/* /*
* adj_parent_rate might have been modified by our clock. * best_parent_rate might have been modified by our clock.
* Unapply the pre-divider if there's one, and give * Unapply the pre-divider if there's one, and give
* the actual frequency the parent needs to run at. * the actual frequency the parent needs to run at.
*/ */
best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1, best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
adj_parent_rate); adj_req.best_parent_rate);
goto out; goto out;
} }
for (i = 0; i < clk_hw_get_num_parents(hw); i++) { for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
unsigned long tmp_rate, parent_rate; struct clk_rate_request tmp_req = *req;
unsigned long parent_rate;
struct clk_hw *parent; struct clk_hw *parent;
parent = clk_hw_get_parent_by_index(hw, i); parent = clk_hw_get_parent_by_index(hw, i);
@ -123,7 +128,12 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
parent_rate = ccu_mux_helper_apply_prediv(common, cm, i, parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
clk_hw_get_rate(parent)); clk_hw_get_rate(parent));
tmp_rate = round(cm, parent, &parent_rate, req->rate, data); tmp_req.best_parent_hw = parent;
tmp_req.best_parent_rate = parent_rate;
ret = round(cm, &tmp_req, data);
if (ret)
continue;
/* /*
* parent_rate might have been modified by our clock. * parent_rate might have been modified by our clock.
@ -131,16 +141,17 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
* the actual frequency the parent needs to run at. * the actual frequency the parent needs to run at.
*/ */
parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i, parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i,
parent_rate); tmp_req.best_parent_rate);
if (tmp_rate == req->rate) {
if (tmp_req.rate == req->rate) {
best_parent = parent; best_parent = parent;
best_parent_rate = parent_rate; best_parent_rate = parent_rate;
best_rate = tmp_rate; best_rate = tmp_req.rate;
goto out; goto out;
} }
if (ccu_is_better_rate(common, req->rate, tmp_rate, best_rate)) { if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) {
best_rate = tmp_rate; best_rate = tmp_req.rate;
best_parent_rate = parent_rate; best_parent_rate = parent_rate;
best_parent = parent; best_parent = parent;
} }

View File

@ -137,11 +137,9 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
int ccu_mux_helper_determine_rate(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common,
struct ccu_mux_internal *cm, struct ccu_mux_internal *cm,
struct clk_rate_request *req, struct clk_rate_request *req,
unsigned long (*round)(struct ccu_mux_internal *, int (*round)(struct ccu_mux_internal *,
struct clk_hw *, struct clk_rate_request *,
unsigned long *, void *),
unsigned long,
void *),
void *data); void *data);
u8 ccu_mux_helper_get_parent(struct ccu_common *common, u8 ccu_mux_helper_get_parent(struct ccu_common *common,
struct ccu_mux_internal *cm); struct ccu_mux_internal *cm);

View File

@ -162,11 +162,9 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
return rate; return rate;
} }
static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, static int ccu_nkm_determine_rate_helper(struct ccu_mux_internal *mux,
struct clk_hw *parent_hw, struct clk_rate_request *req,
unsigned long *parent_rate, void *data)
unsigned long rate,
void *data)
{ {
struct ccu_nkm *nkm = data; struct ccu_nkm *nkm = data;
struct _ccu_nkm _nkm; struct _ccu_nkm _nkm;
@ -179,18 +177,21 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nkm->fixed_post_div; req->rate *= nkm->fixed_post_div;
if (!clk_hw_can_set_rate_parent(&nkm->common.hw)) if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common); req->rate = ccu_nkm_find_best(req->best_parent_rate, req->rate,
&_nkm, &nkm->common);
else else
rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, parent_hw, parent_rate, rate, req->rate = ccu_nkm_find_best_with_parent_adj(&nkm->common,
&_nkm); req->best_parent_hw,
&req->best_parent_rate,
req->rate, &_nkm);
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nkm->fixed_post_div; req->rate /= nkm->fixed_post_div;
return rate; return 0;
} }
static int ccu_nkm_determine_rate(struct clk_hw *hw, static int ccu_nkm_determine_rate(struct clk_hw *hw,
@ -199,7 +200,7 @@ static int ccu_nkm_determine_rate(struct clk_hw *hw,
struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux, return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux,
req, ccu_nkm_round_rate, nkm); req, ccu_nkm_determine_rate_helper, nkm);
} }
static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,