Hi Maxime, Le mardi 04 avril 2023 à 12:11 +0200, Maxime Ripard a écrit : > The Ingenic CGU clocks implements a mux with a set_parent hook, but > doesn't provide a determine_rate implementation. > > This is a bit odd, since set_parent() is there to, as its name > implies, > change the parent of a clock. However, the most likely candidate to > trigger that parent change is a call to clk_set_rate(), with > determine_rate() figuring out which parent is the best suited for a > given rate. > > The other trigger would be a call to clk_set_parent(), but it's far > less > used, and it doesn't look like there's any obvious user for that > clock. > > So, the set_parent hook is effectively unused, possibly because of an > oversight. However, it could also be an explicit decision by the > original author to avoid any reparenting but through an explicit call > to > clk_set_parent(). As I said in the v2 (IIRC), clk_set_parent() is used when re-parenting from the device tree. > > The driver does implement round_rate() though, which means that we > can > change the rate of the clock, but we will never get to change the > parent. > > However, It's hard to tell whether it's been done on purpose or not. > > Since we'll start mandating a determine_rate() implementation, let's > convert the round_rate() implementation to a determine_rate(), which > will also make the current behavior explicit. And if it was an > oversight, the clock behaviour can be adjusted later on. So just to be sure, this patch won't make clk_set_rate() automatically switch parents, right? Allowing automatic re-parenting sounds like a huge can of worms... Cheers, -Paul > > Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> > --- > drivers/clk/ingenic/cgu.c | 15 ++++++++------- > 1 file changed, 8 insertions(+), 7 deletions(-) > > diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c > index 1f7ba30f5a1b..0c9c8344ad11 100644 > --- a/drivers/clk/ingenic/cgu.c > +++ b/drivers/clk/ingenic/cgu.c > @@ -491,22 +491,23 @@ ingenic_clk_calc_div(struct clk_hw *hw, > return div; > } > > -static long > -ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate, > - unsigned long *parent_rate) > +static int ingenic_clk_determine_rate(struct clk_hw *hw, > + struct clk_rate_request *req) > { > struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw); > const struct ingenic_cgu_clk_info *clk_info = > to_clk_info(ingenic_clk); > unsigned int div = 1; > > if (clk_info->type & CGU_CLK_DIV) > - div = ingenic_clk_calc_div(hw, clk_info, > *parent_rate, req_rate); > + div = ingenic_clk_calc_div(hw, clk_info, req- > >best_parent_rate, > + req->rate); > else if (clk_info->type & CGU_CLK_FIXDIV) > div = clk_info->fixdiv.div; > else if (clk_hw_can_set_rate_parent(hw)) > - *parent_rate = req_rate; > + req->best_parent_rate = req->rate; > > - return DIV_ROUND_UP(*parent_rate, div); > + req->rate = DIV_ROUND_UP(req->best_parent_rate, div); > + return 0; > } > > static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu, > @@ -626,7 +627,7 @@ static const struct clk_ops ingenic_clk_ops = { > .set_parent = ingenic_clk_set_parent, > > .recalc_rate = ingenic_clk_recalc_rate, > - .round_rate = ingenic_clk_round_rate, > + .determine_rate = ingenic_clk_determine_rate, > .set_rate = ingenic_clk_set_rate, > > .enable = ingenic_clk_enable, >