diff options
| author | Carlo Caione <[email protected]> | 2026-07-24 10:36:05 +0200 |
|---|---|---|
| committer | David Lechner <[email protected]> | 2026-07-29 11:06:00 -0500 |
| commit | 976b12414c18cb7d601f073dcb2282bac1924197 (patch) | |
| tree | d787b6281d3431f5306ba01537102b266a5bd6bd | |
| parent | 9864f23f45a4b1f837dc873e670b7b00eefc4efc (diff) | |
clk: mediatek: probe parent providers on demand
MediaTek clock trees can reference parents provided by a different clock
controller. The provider registry is populated when each controller
probes, so an early consumer can request a parent before its provider has
been registered.
When lookup misses, find the MediaTek clock device whose operations and
clock-tree type match the requested provider, then probe that device.
This removes the probe-order dependency without probing unrelated clock
controllers or treating a driver's bind callback as a type marker.
Co-developed-by: David Lechner <[email protected]>
Signed-off-by: Carlo Caione <[email protected]>
Link: https://patch.msgid.link/20260724-ccaione-upstream-fix-clk-probe-v2-1-ebcef2e94e9d@baylibre.com
Signed-off-by: David Lechner <[email protected]>
| -rw-r--r-- | drivers/clk/mediatek/clk-mtk.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index ec8175552b0..d4cb23aa0fc 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -9,6 +9,7 @@ #include <clk-uclass.h> #include <div64.h> #include <dm.h> +#include <dm/device-internal.h> #include <asm/io.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -60,6 +61,40 @@ static struct udevice *mtk_clk_tree_get_provider(enum mtk_clk_tree_type type) if (!mtk_clk_tree_type_is_provider(type)) return NULL; + if (!mtk_clk_providers[type]) { + struct udevice *dev; + struct uclass *uc; + int ret; + + /* Lazily probe and register the requested provider. */ + ret = uclass_get(UCLASS_CLK, &uc); + if (ret) + return ERR_PTR(ret); + + uclass_foreach_dev(dev, uc) { + const struct mtk_clk_tree *tree; + const void *ops; + + ops = dev_get_driver_ops(dev); + if (ops != &mtk_clk_apmixedsys_ops && + ops != &mtk_clk_fixed_pll_ops && + ops != &mtk_clk_topckgen_ops && + ops != &mtk_clk_infrasys_ops) + continue; + + tree = (const void *)dev_get_driver_data(dev); + if (tree->type != type) + continue; + + /* Probe will add it to mtk_clk_providers[type]. */ + ret = device_probe(dev); + if (ret) + return ERR_PTR(ret); + + break; + } + } + return mtk_clk_providers[type] ?: ERR_PTR(-ENOENT); } |
