summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlo Caione <[email protected]>2026-07-24 10:36:05 +0200
committerDavid Lechner <[email protected]>2026-07-29 11:06:00 -0500
commit976b12414c18cb7d601f073dcb2282bac1924197 (patch)
treed787b6281d3431f5306ba01537102b266a5bd6bd
parent9864f23f45a4b1f837dc873e670b7b00eefc4efc (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.c35
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);
}