Pass the clock controller udevice into clk_register_composite(), so it can be passed further to any registered composite clocks and used for look up of parent clock referenced in DT "clocks" and "clock-names" properties by phandle and name pair.
Use the clock controller udevice in imx8m_clk_mux_set_parent() to perform accurate look up of parent clock referenced in the CCM driver by name. If the clock name that is being looked up matches one of the names listed in the clock controller DT node "clock-names" array property, then the offset of the name is looked up in the "clocks" DT property and the phandle at that offset is resolved to the parent clock udevice. The test to determine whether a particular driver instance registered with clock uclass matches the parent clock is done by comparing the OF nodes of the clock registered with clock uclass and parent clock resolved from the phandle. Example: drivers/clk/imx/clk-imx8mm.c: static const char * const imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", ... _____________| arch/arm/dts/imx8mm.dtsi: | clk: clock-controller@30380000 { v clock-names = "osc_32k", "osc_24m", ... | v clocks = <&osc_32k>, <&osc_24m>, ... }; _______________________| ... | / { v osc_24m: clock-osc-24m { compatible = "fixed-clock"; ... }; Signed-off-by: Marek Vasut <ma...@denx.de> --- Cc: Adam Ford <aford...@gmail.com> Cc: Christoph Niedermaier <cniederma...@dh-electronics.com> Cc: Dong Aisheng <aisheng.d...@nxp.com> Cc: Fabio Estevam <feste...@gmail.com> Cc: Michael Trimarchi <mich...@amarulasolutions.com> Cc: Peng Fan <peng....@nxp.com> Cc: Sean Anderson <sean...@gmail.com> Cc: Shawn Guo <shawn...@kernel.org> Cc: Tom Rini <tr...@konsulko.com> Cc: u-boot@lists.denx.de --- drivers/clk/clk-composite.c | 2 ++ drivers/clk/imx/clk-composite-8m.c | 30 +++++++++++++++++++++++++++++- include/linux/clk-provider.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 9e3b5191767..207224b1320 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -155,6 +155,8 @@ struct clk *clk_register_composite(struct udevice *dev, const char *name, goto err; } + composite->dev = dev; + if (composite->mux) composite->mux->dev = clk->dev; if (composite->rate) diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 14c5b92939c..e1a3c0af308 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -116,14 +116,42 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = { .set_rate = imx8m_clk_composite_divider_set_rate, }; +static int imx8m_clk_mux_fetch_parent_index(struct udevice *cdev, struct clk *clk, struct clk *parent) +{ + struct clk_mux *mux = to_clk_mux(clk); + struct clk cclk; + int ret; + int i; + + if (!parent) + return -EINVAL; + + for (i = 0; i < mux->num_parents; i++) { + ret = clk_get_by_name(cdev, mux->parent_names[i], &cclk); + if (!ret && ofnode_equal(dev_ofnode(parent->dev), dev_ofnode(cclk.dev))) + return i; + + if (!strcmp(parent->dev->name, mux->parent_names[i])) + return i; + if (!strcmp(parent->dev->name, + clk_resolve_parent_clk(clk->dev, + mux->parent_names[i]))) + return i; + } + + return -EINVAL; +} + + static int imx8m_clk_mux_set_parent(struct clk *clk, struct clk *parent) { struct clk_mux *mux = to_clk_mux(clk); + struct clk_composite *composite = (struct clk_composite *)clk->data; int index; u32 val; u32 reg; - index = clk_mux_fetch_parent_index(clk, parent); + index = imx8m_clk_mux_fetch_parent_index(composite->dev, clk, parent); if (index < 0) { log_err("Could not fetch index\n"); return index; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 5ea2171492e..267757939e0 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -219,6 +219,8 @@ struct clk_composite { const struct clk_ops *mux_ops; const struct clk_ops *rate_ops; const struct clk_ops *gate_ops; + + struct udevice *dev; }; #define to_clk_composite(_clk) container_of(_clk, struct clk_composite, clk) -- 2.47.2