* [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
@ 2026-01-19 19:07 Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL Yang Xiwen via B4 Relay
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson
Cc: u-boot, Yang Xiwen, Simon Glass
Currently, the U-Boot clk framework mandates that clock registration
begins at the root and proceeds to children. This creates an additional
requirement that does not exist in the Linux kernel, making the porting
of clk drivers more difficult.
This series handles the dependency entirely within the clk framework,
allowing drivers the freedom to register clocks in any order.
This is achieved by assigning the parent "lazily". The framework caches
the parent name in the core clk struct and attempts to resolve the
actual parent when clk consumers call clk_get_parent(). The process is
transparent to clk consumers as long as they use standard clk framework
APIs.
I've run `ut dm clk*` and verified these commits do not break any
existing test cases. It also passes the new test case.
This feature is disabled for xPLs by default. I have not found a clean
way to enable this separately for xPLs without introducing a repetitive
Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
Changes in v3:
- dm: core: drop Simon's rb because the logic is incompelete and broken.
I forgot to add the child to the parent's child_node list which fails
the test I've written for the dev_reparent() change. (Simon)
- test: dm: add tests for device_reparent()
- test: clk: rebase onto master, clk_dm() -> dev_clk_dm(), add required
CLK_ID() macro.
- Link to v2: https://lore.kernel.org/r/20260101-clk-reparent-v2-0-3eb42b78c7f1@outlook.com
Changes in v2:
- tests: add a simple test for this feature
- clk: restrict this feature to only U-Boot proper, excluding xPLs from
support (Tom)
- clk: some minor tweaks that should not matter too much
- Link to v1: https://lore.kernel.org/r/20250621-clk-reparent-v1-0-48a7f2f31c59@outlook.com
---
Yang Xiwen (6):
drivers: core: device: set new parent when old parent is NULL
test: dm: core: add some assertions for device_reparent()
clk: add uclass id check to clk_get_parent()
clk: use clk_get_parent() helper in clk_en(dis)able()
clk: allow assigning parent lazily
test: clk: add test for CLK_LAZY_REPARENT
drivers/clk/Kconfig | 12 ++++++++
drivers/clk/clk-uclass.c | 72 +++++++++++++++++++++++++++++++++++--------
drivers/clk/clk.c | 14 +++++++--
drivers/clk/clk_sandbox_ccf.c | 10 ++++++
drivers/core/device.c | 8 +++++
include/clk.h | 2 ++
include/sandbox-clk.h | 2 ++
test/dm/clk_ccf.c | 40 ++++++++++++++++++++++++
test/dm/core.c | 34 ++++++++++++++++++--
9 files changed, 178 insertions(+), 16 deletions(-)
---
base-commit: 6b2d05748cf3cd6ba417a96c00602b0122e10af6
change-id: 20250621-clk-reparent-89d75f6a8e09
Best regards,
--
Yang Xiwen <forbidden405@outlook.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-01-19 19:07 ` [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent() Yang Xiwen via B4 Relay
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson; +Cc: u-boot, Yang Xiwen
From: Yang Xiwen <forbidden405@outlook.com>
The current logic does not update the new parent in device_reparent() if
old parent is NULL. The behavior is not desired. Fix it by setting the
parent in this case.
Fixes: cfecbaf4e768 ("dm: core: add support for device re-parenting")
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
drivers/core/device.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 779f371b9d5b..0ae09f5a4e33 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -285,6 +285,14 @@ int device_reparent(struct udevice *dev, struct udevice *new_parent)
assert(dev);
assert(new_parent);
+ if (!dev->parent) {
+ assert(list_empty(&dev->sibling_node));
+
+ list_add_tail(&dev->sibling_node, &new_parent->child_head);
+ dev->parent = new_parent;
+ return 0;
+ }
+
device_foreach_child_safe(pos, n, dev->parent) {
if (pos->driver != dev->driver)
continue;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent()
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-01-19 19:07 ` [PATCH v3 3/6] clk: add uclass id check to clk_get_parent() Yang Xiwen via B4 Relay
` (4 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson; +Cc: u-boot, Yang Xiwen
From: Yang Xiwen <forbidden405@outlook.com>
The original tests only assert the return value of device_reparent(),
but does not check the actual relation between the new parent and the
child. Add some assertions to check this behavior.
It also lacks the logic to test orphan/root devices. Add tests for that.
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
test/dm/core.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/test/dm/core.c b/test/dm/core.c
index 53693f4f7ed7..ae9415c89563 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -696,9 +696,10 @@ DM_TEST(dm_test_children, 0);
static int dm_test_device_reparent(struct unit_test_state *uts)
{
struct udevice *top[NODE_COUNT];
- struct udevice *child[NODE_COUNT];
+ struct udevice *child[NODE_COUNT], *temp_child = NULL;
struct udevice *grandchild[NODE_COUNT];
struct udevice *dev;
+ struct udevice *orphan;
int total;
int ret;
int i;
@@ -720,8 +721,11 @@ static int dm_test_device_reparent(struct unit_test_state *uts)
ut_assertok(create_children(uts, child[i], NODE_COUNT, 50 * i,
i == 2 ? grandchild : NULL));
+ /* Create an orphan device */
+ ut_assertok(create_children(uts, NULL, 1, 49, &orphan));
+
/* Check total number of devices */
- total = NODE_COUNT * (3 + NODE_COUNT);
+ total = NODE_COUNT * (3 + NODE_COUNT) + 1;
ut_asserteq(total, dm_testdrv_op_count[DM_TEST_OP_BIND]);
/* Probe everything */
@@ -738,6 +742,14 @@ static int dm_test_device_reparent(struct unit_test_state *uts)
ut_assertok(device_reparent(top[4], top[0]));
+ /* Ensure it's reparented */
+ ut_asserteq_ptr(top[4]->parent, top[0]);
+ device_foreach_child(temp_child, top[0]) {
+ if (temp_child == top[4])
+ break;
+ }
+ ut_asserteq_ptr(temp_child, top[4]);
+
/* try to get devices */
ret = uclass_find_first_device(UCLASS_TEST, &dev);
ut_assert(!ret);
@@ -773,6 +785,24 @@ static int dm_test_device_reparent(struct unit_test_state *uts)
ut_assert(!ret);
ut_assertnonnull(dev);
+ /* Re-parent orphant device */
+ ut_assertok(device_reparent(orphan, top[0]));
+
+ /* try to get the device */
+ ret = uclass_find_first_device(UCLASS_TEST, &dev);
+ ut_assert(!ret);
+ ut_assertnonnull(dev);
+
+ /* ensure it's reparented */
+ ut_asserteq_ptr(orphan->parent, top[0]);
+
+ temp_child = NULL;
+ device_foreach_child(temp_child, top[0]) {
+ if (temp_child == orphan)
+ break;
+ }
+ ut_asserteq_ptr(temp_child, orphan);
+
/* Remove re-pareneted devices. */
ut_assertok(device_remove(top[3], DM_REMOVE_NORMAL));
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 3/6] clk: add uclass id check to clk_get_parent()
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent() Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 4/6] clk: use clk_get_parent() helper in clk_en(dis)able() Yang Xiwen via B4 Relay
` (3 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson
Cc: u-boot, Yang Xiwen, Simon Glass
From: Yang Xiwen <forbidden405@outlook.com>
Check the uclass id in clk_get_parent() before casting dev->priv to
struct clk *. This sanity check can be also found in some other places
and should be enforced.
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
drivers/clk/clk-uclass.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 0584429bed65..559420c85056 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -507,6 +507,10 @@ struct clk *clk_get_parent(struct clk *clk)
pdev = dev_get_parent(clk->dev);
if (!pdev)
return ERR_PTR(-ENODEV);
+
+ if (device_get_uclass_id(pdev) != UCLASS_CLK)
+ return ERR_PTR(-ENODEV);
+
pclk = dev_get_clk_ptr(pdev);
if (!pclk)
return ERR_PTR(-ENODEV);
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 4/6] clk: use clk_get_parent() helper in clk_en(dis)able()
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
` (2 preceding siblings ...)
2026-01-19 19:07 ` [PATCH v3 3/6] clk: add uclass id check to clk_get_parent() Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 5/6] clk: allow assigning parent lazily Yang Xiwen via B4 Relay
` (2 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson
Cc: u-boot, Yang Xiwen, Simon Glass
From: Yang Xiwen <forbidden405@outlook.com>
Update clk_enable() and clk_disable() to use clk_get_parent() instead of
manually accessing clk->dev->parent.
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
drivers/clk/clk-uclass.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 559420c85056..297d4d63a579 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -663,7 +663,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
int clk_enable(struct clk *clk)
{
const struct clk_ops *ops;
- struct clk *clkp = NULL;
+ struct clk *clkp = NULL, *clk_parent;
int ret;
debug("%s(clk=%p name=%s)\n", __func__, clk, clk ? clk->dev->name : "NULL");
@@ -679,9 +679,10 @@ int clk_enable(struct clk *clk)
clkp->enable_count++;
return 0;
}
- if (clkp->dev->parent &&
- device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
- ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
+
+ clk_parent = clk_get_parent(clkp);
+ if (!IS_ERR_OR_NULL(clk_parent)) {
+ ret = clk_enable(clk_parent);
if (ret) {
printf("Enable %s failed\n",
clkp->dev->parent->name);
@@ -754,13 +755,16 @@ int clk_disable(struct clk *clk)
return ret;
}
- if (clkp && clkp->dev->parent &&
- device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
- ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
- if (ret) {
- printf("Disable %s failed\n",
- clkp->dev->parent->name);
- return ret;
+ if (clkp) {
+ struct clk *clk_parent = clk_get_parent(clkp);
+
+ if (!IS_ERR_OR_NULL(clk_parent)) {
+ ret = clk_disable(clk_parent);
+ if (ret) {
+ printf("Disable %s failed\n",
+ clkp->dev->parent->name);
+ return ret;
+ }
}
}
} else {
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 5/6] clk: allow assigning parent lazily
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
` (3 preceding siblings ...)
2026-01-19 19:07 ` [PATCH v3 4/6] clk: use clk_get_parent() helper in clk_en(dis)able() Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT Yang Xiwen via B4 Relay
2026-02-02 20:17 ` [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Tom Rini
6 siblings, 0 replies; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson
Cc: u-boot, Yang Xiwen, Simon Glass
From: Yang Xiwen <forbidden405@outlook.com>
Don't mandate the parent device exists when registering a clock.
Instead, cache the parent name in the core clk struct and resolve the
parent in clk_get_parent(), which is called lazily upon real use.
Disable this feature for xPLs by default to save size.
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
drivers/clk/Kconfig | 12 ++++++++++++
drivers/clk/clk-uclass.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
drivers/clk/clk.c | 14 ++++++++++++--
include/clk.h | 2 ++
4 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index ae783254008c..5a57adef3ccb 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -51,6 +51,18 @@ config VPL_CLK
setting up clocks within TPL, and allows the same drivers to be
used as U-Boot proper.
+config CLK_LAZY_REPARENT
+ bool "Enable clock lazy reparenting feature"
+ depends on CLK_CCF
+ default n if SPL_CLK || TPL_CLK || VPL_CLK
+ default y
+ help
+ This option allows registering clocks in a less strict order that
+ Parent clocks can be registered before their children. The clock subsystem
+ will cache the parent's name and resolve it to the real parent device "lazily".
+ This is the default behavior in Linux clock subsystem. Enabling this feature
+ should simplifies the porting of Linux clock drivers to U-Boot.
+
config CLK_BCM6345
bool "Clock controller driver for BCM6345"
depends on CLK && ARCH_BMIPS
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 297d4d63a579..a7f02d339a55 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -495,6 +495,32 @@ ulong clk_get_rate(struct clk *clk)
return ops->get_rate(clk);
}
+static struct udevice *clk_reparent(struct clk *clk, const char *parent_name)
+{
+ struct udevice *pdev;
+ int ret;
+
+ if (!clk_valid(clk))
+ return NULL;
+
+ if (!parent_name)
+ return NULL;
+
+ debug("%s(clk=%p) reparenting to %s\n", __func__, clk, parent_name);
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &pdev);
+ if (ret) {
+ log_err("%s(clk=%p) failed to find parent \"%s\"\n", __func__, clk, parent_name);
+ return NULL;
+ }
+
+ ret = device_reparent(clk->dev, pdev);
+ if (ret)
+ return NULL;
+
+ return pdev;
+}
+
struct clk *clk_get_parent(struct clk *clk)
{
struct udevice *pdev;
@@ -505,8 +531,18 @@ struct clk *clk_get_parent(struct clk *clk)
return NULL;
pdev = dev_get_parent(clk->dev);
- if (!pdev)
- return ERR_PTR(-ENODEV);
+ if (!pdev) {
+ if (CONFIG_IS_ENABLED(CLK_LAZY_REPARENT)) {
+ pdev = clk_reparent(clk, clk->parent_name);
+ free(clk->parent_name);
+ clk->parent_name = NULL;
+
+ if (!pdev)
+ return ERR_PTR(-ENODEV);
+ } else {
+ return ERR_PTR(-ENODEV);
+ }
+ }
if (device_get_uclass_id(pdev) != UCLASS_CLK)
return ERR_PTR(-ENODEV);
@@ -630,6 +666,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);
if (!clk_valid(clk))
return 0;
+
+ free(clk->parent_name);
+ clk->parent_name = NULL;
+
ops = clk_dev_ops(clk->dev);
if (!ops->set_parent)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b8c2e8d531b9..32b3c03ab09a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -24,8 +24,18 @@ int clk_register(struct clk *clk, const char *drv_name,
if (parent_name) {
ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent);
if (ret) {
- log_err("%s: failed to get %s device (parent of %s)\n",
- __func__, parent_name, name);
+ log_debug("%s: failed to get %s device (parent of %s)\n",
+ __func__, parent_name, name);
+
+ if (CONFIG_IS_ENABLED(CLK_LAZY_REPARENT)) {
+ /*
+ * The parent is not yet registered.
+ * Cache the parent name and resolve it later.
+ */
+ clk->parent_name = strdup(parent_name);
+ if (!clk->parent_name)
+ return -ENOMEM;
+ }
} else {
log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name,
parent->name, parent);
diff --git a/include/clk.h b/include/clk.h
index 90b42a618675..88db75c56d44 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -47,6 +47,7 @@ struct udevice;
/**
* struct clk - A handle to (allowing control of) a single clock.
* @dev: The device which implements the clock signal.
+ * @parent_name: The name of the parent.
* @rate: The clock rate (in HZ).
* @flags: Flags used across common clock structure (e.g. %CLK_)
* Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
@@ -72,6 +73,7 @@ struct udevice;
*/
struct clk {
struct udevice *dev;
+ char *parent_name;
long long rate; /* in HZ */
u32 flags;
int enable_count;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
` (4 preceding siblings ...)
2026-01-19 19:07 ` [PATCH v3 5/6] clk: allow assigning parent lazily Yang Xiwen via B4 Relay
@ 2026-01-19 19:07 ` Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-02-02 20:17 ` [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Tom Rini
6 siblings, 1 reply; 15+ messages in thread
From: Yang Xiwen via B4 Relay @ 2026-01-19 19:07 UTC (permalink / raw)
To: Simon Glass, Tom Rini, Lukasz Majewski, Sean Anderson; +Cc: u-boot, Yang Xiwen
From: Yang Xiwen <forbidden405@outlook.com>
Add a test for the newly introduced CLK_LAZY_REPARENT feature.
Modify clk_sandbox_ccf driver to register two clocks(i2s and i2s_root)
in reversed order.
The test function then try to acquire the clocks and asserts that their
internal states are maintained correctly.
Ensure clk->parent_name is NULL in all "normal" cases so existing
drivers are not broken by this feature.
Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
---
drivers/clk/clk_sandbox_ccf.c | 10 ++++++++++
include/sandbox-clk.h | 2 ++
test/dm/clk_ccf.c | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+)
diff --git a/drivers/clk/clk_sandbox_ccf.c b/drivers/clk/clk_sandbox_ccf.c
index 9b8036d41aac..86f75132d548 100644
--- a/drivers/clk/clk_sandbox_ccf.c
+++ b/drivers/clk/clk_sandbox_ccf.c
@@ -229,6 +229,7 @@ static const struct udevice_id sandbox_clk_ccf_test_ids[] = {
static const char *const usdhc_sels[] = { "pll3_60m", "pll3_80m", };
static const char *const i2c_sels[] = { "pll3_60m", "pll3_80m", };
+static const char *const i2s_sels[] = { "pll3_60m", "pll3_80m", };
static int sandbox_clk_ccf_probe(struct udevice *dev)
{
@@ -277,6 +278,15 @@ static int sandbox_clk_ccf_probe(struct udevice *dev)
dev_clk_dm(dev, SANDBOX_CLK_I2C_ROOT,
sandbox_clk_gate2("i2c_root", "i2c", base + 0x7c, 0));
+ /* Register i2s_root(child) and i2s(parent) in reverse order to test CLK_LAZY_REPARENT */
+ dev_clk_dm(dev, SANDBOX_CLK_I2S_ROOT,
+ sandbox_clk_gate2("i2s_root", "i2s", base + 0x80, 0));
+
+ reg = BIT(29) | BIT(25) | BIT(17);
+ dev_clk_dm(dev, SANDBOX_CLK_I2S,
+ sandbox_clk_composite("i2s", i2s_sels, ARRAY_SIZE(i2s_sels),
+ ®, CLK_SET_RATE_UNGATE));
+
return 0;
}
diff --git a/include/sandbox-clk.h b/include/sandbox-clk.h
index c2616c27a44a..0cd735e3ad5f 100644
--- a/include/sandbox-clk.h
+++ b/include/sandbox-clk.h
@@ -21,6 +21,8 @@ enum {
SANDBOX_CLK_USDHC2_SEL,
SANDBOX_CLK_I2C,
SANDBOX_CLK_I2C_ROOT,
+ SANDBOX_CLK_I2S,
+ SANDBOX_CLK_I2S_ROOT,
};
enum sandbox_pllv3_type {
diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c
index 9c06aadb7ed3..8bbb79bec2ac 100644
--- a/test/dm/clk_ccf.c
+++ b/test/dm/clk_ccf.c
@@ -35,12 +35,14 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_ECSPI_ROOT), &clk);
ut_assertok(ret);
ut_asserteq_str("ecspi_root", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
/* Test for clk_get_parent_rate() */
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_ECSPI1), &clk);
ut_assertok(ret);
ut_asserteq_str("ecspi1", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
rate = clk_get_parent_rate(clk);
@@ -50,6 +52,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_ECSPI0), &clk);
ut_assertok(ret);
ut_asserteq_str("ecspi0", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
rate = clk_get_parent_rate(clk);
@@ -59,6 +62,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_USDHC1_SEL), &clk);
ut_assertok(ret);
ut_asserteq_str("usdhc1_sel", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_NO_REPARENT, clk->flags);
rate = clk_get_parent_rate(clk);
@@ -71,6 +75,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ut_asserteq_64(60000000, rate);
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_PLL3_80M), &pclk);
+ ut_assertnull(clk->parent_name);
ut_assertok(ret);
ret = clk_set_parent(clk, pclk);
@@ -82,6 +87,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_USDHC2_SEL), &clk);
ut_assertok(ret);
ut_asserteq_str("usdhc2_sel", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_NO_REPARENT, clk->flags);
rate = clk_get_parent_rate(clk);
@@ -98,6 +104,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ut_asserteq_64(80000000, rate);
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_PLL3_60M), &pclk);
+ ut_assertnull(clk->parent_name);
ut_assertok(ret);
ret = clk_set_parent(clk, pclk);
@@ -110,6 +117,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2C), &clk);
ut_assertok(ret);
ut_asserteq_str("i2c", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_SET_RATE_UNGATE, clk->flags);
rate = clk_get_rate(clk);
@@ -124,11 +132,13 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_index(test_dev, SANDBOX_CLK_TEST_ID_I2C_ROOT, &clk_ccf);
ut_assertok(ret);
ut_asserteq_str("clk-ccf", clk_ccf.dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(CLK_ID(clk_ccf.dev, SANDBOX_CLK_I2C_ROOT), clk_ccf.id);
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2C_ROOT), &clk);
ut_assertok(ret);
ut_asserteq_str("i2c_root", clk->dev->name);
+ ut_assertnull(clk->parent_name);
ut_asserteq(SANDBOX_CLK_I2C_ROOT, clk_get_id(clk));
ret = clk_enable(&clk_ccf);
@@ -138,6 +148,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ut_asserteq(1, ret);
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2C), &pclk);
+ ut_assertnull(clk->parent_name);
ut_assertok(ret);
ret = sandbox_clk_enable_count(pclk);
@@ -156,6 +167,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_USDHC1_SEL), &clk);
ut_assertok(ret);
ut_asserteq_str("usdhc1_sel", clk->dev->name);
+ ut_assertnull(clk->parent_name);
pclk = clk_get_parent(clk);
ut_assertok_ptr(pclk);
@@ -169,6 +181,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, clkid), &pclk);
ut_assertok(ret);
+ ut_assertnull(clk->parent_name);
ret = clk_set_parent(clk, pclk);
ut_assertok(ret);
pclk = clk_get_parent(clk);
@@ -179,6 +192,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2C_ROOT), &clk);
ut_assertok(ret);
ut_asserteq_str("i2c_root", clk->dev->name);
+ ut_assertnull(clk->parent_name);
/* Disable it, if any. */
ret = sandbox_clk_enable_count(clk);
@@ -209,3 +223,29 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
return 1;
}
DM_TEST(dm_test_clk_ccf, UTF_SCAN_FDT);
+
+#if CONFIG_IS_ENABLED(CLK_LAZY_REPARENT)
+/* Test CLK_LAZY_REPARENT feature */
+static int dm_test_clk_lazy_reparent(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct clk *clk_i2s, *clk_i2s_root;
+
+ /* Get the device using the clk device */
+ ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev));
+
+ ut_assertok(clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2S_ROOT), &clk_i2s_root));
+ ut_assertok(clk_get_by_id(CLK_ID(dev, SANDBOX_CLK_I2S), &clk_i2s));
+
+ ut_asserteq_str(clk_i2s_root->parent_name, "i2s");
+ ut_assertnull(clk_i2s_root->dev->parent);
+
+ ut_assertok(clk_enable(clk_i2s_root));
+
+ ut_assertnull(clk_i2s_root->parent_name);
+ ut_asserteq_ptr(clk_i2s_root->dev->parent, clk_i2s->dev);
+
+ return 0;
+}
+DM_TEST(dm_test_clk_lazy_reparent, UTF_SCAN_FDT);
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
` (5 preceding siblings ...)
2026-01-19 19:07 ` [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT Yang Xiwen via B4 Relay
@ 2026-02-02 20:17 ` Tom Rini
2026-02-03 15:28 ` Yang Xiwen
6 siblings, 1 reply; 15+ messages in thread
From: Tom Rini @ 2026-02-02 20:17 UTC (permalink / raw)
To: Yang Xiwen
Cc: Simon Glass, Lukasz Majewski, Sean Anderson, u-boot, Simon Glass
[-- Attachment #1: Type: text/plain, Size: 1379 bytes --]
On Tue, Jan 20, 2026 at 03:07:17AM +0800, Yang Xiwen wrote:
> Currently, the U-Boot clk framework mandates that clock registration
> begins at the root and proceeds to children. This creates an additional
> requirement that does not exist in the Linux kernel, making the porting
> of clk drivers more difficult.
>
> This series handles the dependency entirely within the clk framework,
> allowing drivers the freedom to register clocks in any order.
>
> This is achieved by assigning the parent "lazily". The framework caches
> the parent name in the core clk struct and attempts to resolve the
> actual parent when clk consumers call clk_get_parent(). The process is
> transparent to clk consumers as long as they use standard clk framework
> APIs.
>
> I've run `ut dm clk*` and verified these commits do not break any
> existing test cases. It also passes the new test case.
>
> This feature is disabled for xPLs by default. I have not found a clean
> way to enable this separately for xPLs without introducing a repetitive
> Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
>
> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
This, like some previous clk reworks, leads to run-time breakage
(failure to boot) on TI K3 and likely other platforms (I want to say
some rockchip was broken last time) as well.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
2026-02-02 20:17 ` [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Tom Rini
@ 2026-02-03 15:28 ` Yang Xiwen
2026-02-03 16:15 ` Tom Rini
0 siblings, 1 reply; 15+ messages in thread
From: Yang Xiwen @ 2026-02-03 15:28 UTC (permalink / raw)
To: Tom Rini; +Cc: Simon Glass, Lukasz Majewski, Sean Anderson, u-boot, Simon Glass
On 2/3/2026 4:17 AM, Tom Rini wrote:
> On Tue, Jan 20, 2026 at 03:07:17AM +0800, Yang Xiwen wrote:
>
>> Currently, the U-Boot clk framework mandates that clock registration
>> begins at the root and proceeds to children. This creates an additional
>> requirement that does not exist in the Linux kernel, making the porting
>> of clk drivers more difficult.
>>
>> This series handles the dependency entirely within the clk framework,
>> allowing drivers the freedom to register clocks in any order.
>>
>> This is achieved by assigning the parent "lazily". The framework caches
>> the parent name in the core clk struct and attempts to resolve the
>> actual parent when clk consumers call clk_get_parent(). The process is
>> transparent to clk consumers as long as they use standard clk framework
>> APIs.
>>
>> I've run `ut dm clk*` and verified these commits do not break any
>> existing test cases. It also passes the new test case.
>>
>> This feature is disabled for xPLs by default. I have not found a clean
>> way to enable this separately for xPLs without introducing a repetitive
>> Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
>>
>> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> This, like some previous clk reworks, leads to run-time breakage
> (failure to boot) on TI K3 and likely other platforms (I want to say
> some rockchip was broken last time) as well.
>
It's sad to hear that. Could you please provide the log so I can try to
fix that? This also means our testcases can't cover all cases.
This feature is required by an upcoming Amlogic meson8b clk driver. So I
want this to be merged eventually.
--
Regards,
Yang Xiwen
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
2026-02-03 15:28 ` Yang Xiwen
@ 2026-02-03 16:15 ` Tom Rini
2026-02-07 14:58 ` Yang Xiwen
0 siblings, 1 reply; 15+ messages in thread
From: Tom Rini @ 2026-02-03 16:15 UTC (permalink / raw)
To: Yang Xiwen
Cc: Simon Glass, Lukasz Majewski, Sean Anderson, u-boot, Simon Glass
[-- Attachment #1: Type: text/plain, Size: 4466 bytes --]
On Tue, Feb 03, 2026 at 11:28:03PM +0800, Yang Xiwen wrote:
> On 2/3/2026 4:17 AM, Tom Rini wrote:
> > On Tue, Jan 20, 2026 at 03:07:17AM +0800, Yang Xiwen wrote:
> >
> > > Currently, the U-Boot clk framework mandates that clock registration
> > > begins at the root and proceeds to children. This creates an additional
> > > requirement that does not exist in the Linux kernel, making the porting
> > > of clk drivers more difficult.
> > >
> > > This series handles the dependency entirely within the clk framework,
> > > allowing drivers the freedom to register clocks in any order.
> > >
> > > This is achieved by assigning the parent "lazily". The framework caches
> > > the parent name in the core clk struct and attempts to resolve the
> > > actual parent when clk consumers call clk_get_parent(). The process is
> > > transparent to clk consumers as long as they use standard clk framework
> > > APIs.
> > >
> > > I've run `ut dm clk*` and verified these commits do not break any
> > > existing test cases. It also passes the new test case.
> > >
> > > This feature is disabled for xPLs by default. I have not found a clean
> > > way to enable this separately for xPLs without introducing a repetitive
> > > Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
> > >
> > > Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> > This, like some previous clk reworks, leads to run-time breakage
> > (failure to boot) on TI K3 and likely other platforms (I want to say
> > some rockchip was broken last time) as well.
> >
>
> It's sad to hear that. Could you please provide the log so I can try to fix
> that? This also means our testcases can't cover all cases.
On am62x_beagleplay_a53 + am62x_beagleplay_r5:
U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:07:42 +0000)
SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
Set clock rates for '/a53@0', CPU: 1250MHz at Speed Grade 'T'
SPL initial stack usage: 13464 bytes
Trying to boot from MMC2
Starting ATF on ARM64 core...
NOTICE: BL31: v2.10.0(release):v2.10.0-729-gc8be7c08c
NOTICE: BL31: Built : 14:04:51, Jun 24 2024
I/TC:
I/TC: OP-TEE version: 4.2.0-22-g16fbd46d2 (gcc version 13.2.0 (GCC)) #4 Mon Jun 24 20:04:07 U
TC 2024 aarch64
I/TC: WARNING: This OP-TEE configuration might be insecure!
I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guide
lines.html
I/TC: Primary CPU initializing
I/TC: GIC redistributor base address not provided
I/TC: Assuming default GIC group status and modifier
I/TC: SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
I/TC: HUK Initialized
I/TC: Primary CPU switching to normal world boot
U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
SPL initial stack usage: 2048 bytes
Trying to boot from MMC2
U-Boot 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
SoC: AM62X SR1.0 GP
Reset reason: POR
Model: BeagleBoard.org BeaglePlay
DRAM: 2 GiB
I/TC: Reserved shared memory is enabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
Core: 112 devices, 33 uclasses, devicetree: separate
MMC: mmc@fa10000: 0, mmc@fa00000: 1, mmc@fa20000: 2
Loading Environment from nowhere... OK
In: serial@2800000
Out: serial@2800000
Err: serial@2800000
Net: "Synchronous Abort" handler, esr 0x02000000
elr: 00000000808c1b28 lr : 00000000808357b0 (reloc)
elr: 00000000fffd2b28 lr : 00000000fff467b0
x0 : 00000000fdef7340 x1 : 00000000fffd2b28
x2 : 000000000000000a x3 : 0000000000000000
x4 : 000000000000000d x5 : 0000000000000064
x6 : 00000000fffb088b x7 : 0000000000000044
x8 : 000000000000000a x9 : 0000000000000034
x10: 0000000000000002 x11: 00000000ffffffff
x12: 00000000fdede730 x13: 0000000000007040
x14: 00000000fdede730 x15: 00000000ffffffff
x16: 00000000fff53ac8 x17: 0000000000000000
x18: 00000000fdef1e10 x19: 0000000000000000
x20: 00000000fdef7340 x21: 00000000fffccfc0
x22: 00000000fffd4ed0 x23: 00000000fffd4000
x24: 00000000fdefac18 x25: 00000000fdefac18
x26: 00000000fff7bcfc x27: 00000000fff7bdb4
x28: 00000000fffaa8f0 x29: 00000000fdede5b0
Code: fffd2b08 00000000 fffd2b08 00000000 (fffd2b18)
Resetting CPU ...
resetting ...
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT
2026-01-19 19:07 ` [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT Yang Xiwen via B4 Relay
@ 2026-02-04 0:23 ` Simon Glass
0 siblings, 0 replies; 15+ messages in thread
From: Simon Glass @ 2026-02-04 0:23 UTC (permalink / raw)
To: forbidden405; +Cc: Tom Rini, Lukasz Majewski, Sean Anderson, u-boot
On Tue, 20 Jan 2026 at 08:07, Yang Xiwen via B4 Relay
<devnull+forbidden405.outlook.com@kernel.org> wrote:
>
> From: Yang Xiwen <forbidden405@outlook.com>
>
> Add a test for the newly introduced CLK_LAZY_REPARENT feature.
>
> Modify clk_sandbox_ccf driver to register two clocks(i2s and i2s_root)
> in reversed order.
>
> The test function then try to acquire the clocks and asserts that their
> internal states are maintained correctly.
>
> Ensure clk->parent_name is NULL in all "normal" cases so existing
> drivers are not broken by this feature.
>
> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> ---
> drivers/clk/clk_sandbox_ccf.c | 10 ++++++++++
> include/sandbox-clk.h | 2 ++
> test/dm/clk_ccf.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 52 insertions(+)
Reviewed-by: Simon Glass <simon.glass@canonical.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL
2026-01-19 19:07 ` [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL Yang Xiwen via B4 Relay
@ 2026-02-04 0:23 ` Simon Glass
0 siblings, 0 replies; 15+ messages in thread
From: Simon Glass @ 2026-02-04 0:23 UTC (permalink / raw)
To: forbidden405; +Cc: Tom Rini, Lukasz Majewski, Sean Anderson, u-boot
On Tue, 20 Jan 2026 at 08:07, Yang Xiwen via B4 Relay
<devnull+forbidden405.outlook.com@kernel.org> wrote:
>
> From: Yang Xiwen <forbidden405@outlook.com>
>
> The current logic does not update the new parent in device_reparent() if
> old parent is NULL. The behavior is not desired. Fix it by setting the
> parent in this case.
>
> Fixes: cfecbaf4e768 ("dm: core: add support for device re-parenting")
> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> ---
> drivers/core/device.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Separately from this series, I would like to see a function to set the
parent for a device, since this is a fairly unusual thing to do.
Regards,
Simon
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent()
2026-01-19 19:07 ` [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent() Yang Xiwen via B4 Relay
@ 2026-02-04 0:23 ` Simon Glass
0 siblings, 0 replies; 15+ messages in thread
From: Simon Glass @ 2026-02-04 0:23 UTC (permalink / raw)
To: forbidden405; +Cc: Tom Rini, Lukasz Majewski, Sean Anderson, u-boot
On Tue, 20 Jan 2026 at 08:07, Yang Xiwen via B4 Relay
<devnull+forbidden405.outlook.com@kernel.org> wrote:
>
> From: Yang Xiwen <forbidden405@outlook.com>
>
> The original tests only assert the return value of device_reparent(),
> but does not check the actual relation between the new parent and the
> child. Add some assertions to check this behavior.
>
> It also lacks the logic to test orphan/root devices. Add tests for that.
>
> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> ---
> test/dm/core.c | 34 ++++++++++++++++++++++++++++++++--
> 1 file changed, 32 insertions(+), 2 deletions(-)
>
Reviewed-by: Simon Glass <simon.glass@canonical.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
2026-02-03 16:15 ` Tom Rini
@ 2026-02-07 14:58 ` Yang Xiwen
2026-02-09 14:23 ` Tom Rini
0 siblings, 1 reply; 15+ messages in thread
From: Yang Xiwen @ 2026-02-07 14:58 UTC (permalink / raw)
To: Tom Rini; +Cc: Simon Glass, Lukasz Majewski, Sean Anderson, u-boot, Simon Glass
On 2/4/2026 12:15 AM, Tom Rini wrote:
> On Tue, Feb 03, 2026 at 11:28:03PM +0800, Yang Xiwen wrote:
>> On 2/3/2026 4:17 AM, Tom Rini wrote:
>>> On Tue, Jan 20, 2026 at 03:07:17AM +0800, Yang Xiwen wrote:
>>>
>>>> Currently, the U-Boot clk framework mandates that clock registration
>>>> begins at the root and proceeds to children. This creates an additional
>>>> requirement that does not exist in the Linux kernel, making the porting
>>>> of clk drivers more difficult.
>>>>
>>>> This series handles the dependency entirely within the clk framework,
>>>> allowing drivers the freedom to register clocks in any order.
>>>>
>>>> This is achieved by assigning the parent "lazily". The framework caches
>>>> the parent name in the core clk struct and attempts to resolve the
>>>> actual parent when clk consumers call clk_get_parent(). The process is
>>>> transparent to clk consumers as long as they use standard clk framework
>>>> APIs.
>>>>
>>>> I've run `ut dm clk*` and verified these commits do not break any
>>>> existing test cases. It also passes the new test case.
>>>>
>>>> This feature is disabled for xPLs by default. I have not found a clean
>>>> way to enable this separately for xPLs without introducing a repetitive
>>>> Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
>>>>
>>>> Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
>>> This, like some previous clk reworks, leads to run-time breakage
>>> (failure to boot) on TI K3 and likely other platforms (I want to say
>>> some rockchip was broken last time) as well.
>>>
>> It's sad to hear that. Could you please provide the log so I can try to fix
>> that? This also means our testcases can't cover all cases.
> On am62x_beagleplay_a53 + am62x_beagleplay_r5:
> U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:07:42 +0000)
> SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> Set clock rates for '/a53@0', CPU: 1250MHz at Speed Grade 'T'
> SPL initial stack usage: 13464 bytes
> Trying to boot from MMC2
> Starting ATF on ARM64 core...
>
> NOTICE: BL31: v2.10.0(release):v2.10.0-729-gc8be7c08c
> NOTICE: BL31: Built : 14:04:51, Jun 24 2024
> I/TC:
> I/TC: OP-TEE version: 4.2.0-22-g16fbd46d2 (gcc version 13.2.0 (GCC)) #4 Mon Jun 24 20:04:07 U
> TC 2024 aarch64
> I/TC: WARNING: This OP-TEE configuration might be insecure!
> I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guide
> lines.html
> I/TC: Primary CPU initializing
> I/TC: GIC redistributor base address not provided
> I/TC: Assuming default GIC group status and modifier
> I/TC: SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> I/TC: HUK Initialized
> I/TC: Primary CPU switching to normal world boot
>
> U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
> SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> SPL initial stack usage: 2048 bytes
> Trying to boot from MMC2
>
>
> U-Boot 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
>
> SoC: AM62X SR1.0 GP
> Reset reason: POR
> Model: BeagleBoard.org BeaglePlay
> DRAM: 2 GiB
> I/TC: Reserved shared memory is enabled
> I/TC: Dynamic shared memory is enabled
> I/TC: Normal World virtualization support is disabled
> I/TC: Asynchronous notifications are disabled
> Core: 112 devices, 33 uclasses, devicetree: separate
> MMC: mmc@fa10000: 0, mmc@fa00000: 1, mmc@fa20000: 2
> Loading Environment from nowhere... OK
> In: serial@2800000
> Out: serial@2800000
> Err: serial@2800000
> Net: "Synchronous Abort" handler, esr 0x02000000
> elr: 00000000808c1b28 lr : 00000000808357b0 (reloc)
> elr: 00000000fffd2b28 lr : 00000000fff467b0
> x0 : 00000000fdef7340 x1 : 00000000fffd2b28
> x2 : 000000000000000a x3 : 0000000000000000
> x4 : 000000000000000d x5 : 0000000000000064
> x6 : 00000000fffb088b x7 : 0000000000000044
> x8 : 000000000000000a x9 : 0000000000000034
> x10: 0000000000000002 x11: 00000000ffffffff
> x12: 00000000fdede730 x13: 0000000000007040
> x14: 00000000fdede730 x15: 00000000ffffffff
> x16: 00000000fff53ac8 x17: 0000000000000000
> x18: 00000000fdef1e10 x19: 0000000000000000
> x20: 00000000fdef7340 x21: 00000000fffccfc0
> x22: 00000000fffd4ed0 x23: 00000000fffd4000
> x24: 00000000fdefac18 x25: 00000000fdefac18
> x26: 00000000fff7bcfc x27: 00000000fff7bdb4
> x28: 00000000fffaa8f0 x29: 00000000fdede5b0
>
> Code: fffd2b08 00000000 fffd2b08 00000000 (fffd2b18)
> Resetting CPU ...
>
> resetting ...
>
Is the uboot image built by buildman toolchain or some other toolchain?
I've tried to generate the image with `tools/buildman/buildman -M -k
am62x_beagleplay_r5` and debug it with `gdb-multiarch
../current/am62x_beagleplay_r5/u-boot`. But the result doesn't seem correct.
The output of gdb:
(gdb) disas/r 0x808357b0
Dump of assembler code for function menu_destroy.isra.0:
0x8083578c <+0>: b5f8 push {r3, r4, r5, r6, r7, lr}
0x8083578e <+2>: 4605 mov r5, r0
0x80835790 <+4>: 4604 mov r4, r0
0x80835792 <+6>: f855 3f24 ldr.w r3, [r5, #36]!
0x80835796 <+10>: 681e ldr r6, [r3, #0]
0x80835798 <+12>: 42ab cmp r3, r5
0x8083579a <+14>: d108 bne.n 0x808357ae
<menu_destroy.isra.0+34>
0x8083579c <+16>: 68a0 ldr r0, [r4, #8]
0x8083579e <+18>: b108 cbz r0, 0x808357a4
<menu_destroy.isra.0+24>
0x808357a0 <+20>: f7d6 fae6 bl 0x8080bd70 <free>
0x808357a4 <+24>: 4620 mov r0, r4
0x808357a6 <+26>: e8bd 40f8 ldmia.w sp!, {r3, r4, r5, r6,
r7, lr}
0x808357aa <+30>: f7d6 bae1 b.w 0x8080bd70 <free>
0x808357ae <+34>: f853 0c08 ldr.w r0, [r3, #-8]
0x808357b2 <+38>: f1a3 0708 sub.w r7, r3, #8
0x808357b6 <+42>: b108 cbz r0, 0x808357bc
<menu_destroy.isra.0+48>
0x808357b8 <+44>: f7d6 fada bl 0x8080bd70 <free>
0x808357bc <+48>: 4638 mov r0, r7
0x808357be <+50>: f7d6 fad7 bl 0x8080bd70 <free>
0x808357c2 <+54>: 4633 mov r3, r6
0x808357c4 <+56>: 6836 ldr r6, [r6, #0]
0x808357c6 <+58>: e7e7 b.n 0x80835798
<menu_destroy.isra.0+12>
End of assembler dump.
--
Regards,
Yang Xiwen
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v3 0/6] clk: support arbitrary clk_register() sequence
2026-02-07 14:58 ` Yang Xiwen
@ 2026-02-09 14:23 ` Tom Rini
0 siblings, 0 replies; 15+ messages in thread
From: Tom Rini @ 2026-02-09 14:23 UTC (permalink / raw)
To: Yang Xiwen
Cc: Simon Glass, Lukasz Majewski, Sean Anderson, u-boot, Simon Glass
[-- Attachment #1: Type: text/plain, Size: 7108 bytes --]
On Sat, Feb 07, 2026 at 10:58:16PM +0800, Yang Xiwen wrote:
> On 2/4/2026 12:15 AM, Tom Rini wrote:
> > On Tue, Feb 03, 2026 at 11:28:03PM +0800, Yang Xiwen wrote:
> > > On 2/3/2026 4:17 AM, Tom Rini wrote:
> > > > On Tue, Jan 20, 2026 at 03:07:17AM +0800, Yang Xiwen wrote:
> > > >
> > > > > Currently, the U-Boot clk framework mandates that clock registration
> > > > > begins at the root and proceeds to children. This creates an additional
> > > > > requirement that does not exist in the Linux kernel, making the porting
> > > > > of clk drivers more difficult.
> > > > >
> > > > > This series handles the dependency entirely within the clk framework,
> > > > > allowing drivers the freedom to register clocks in any order.
> > > > >
> > > > > This is achieved by assigning the parent "lazily". The framework caches
> > > > > the parent name in the core clk struct and attempts to resolve the
> > > > > actual parent when clk consumers call clk_get_parent(). The process is
> > > > > transparent to clk consumers as long as they use standard clk framework
> > > > > APIs.
> > > > >
> > > > > I've run `ut dm clk*` and verified these commits do not break any
> > > > > existing test cases. It also passes the new test case.
> > > > >
> > > > > This feature is disabled for xPLs by default. I have not found a clean
> > > > > way to enable this separately for xPLs without introducing a repetitive
> > > > > Kconfig entry (e.g., xPL_CLK_LAZY_REPARENT), which looks very ugly.
> > > > >
> > > > > Signed-off-by: Yang Xiwen <forbidden405@outlook.com>
> > > > This, like some previous clk reworks, leads to run-time breakage
> > > > (failure to boot) on TI K3 and likely other platforms (I want to say
> > > > some rockchip was broken last time) as well.
> > > >
> > > It's sad to hear that. Could you please provide the log so I can try to fix
> > > that? This also means our testcases can't cover all cases.
> > On am62x_beagleplay_a53 + am62x_beagleplay_r5:
> > U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:07:42 +0000)
> > SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> > Set clock rates for '/a53@0', CPU: 1250MHz at Speed Grade 'T'
> > SPL initial stack usage: 13464 bytes
> > Trying to boot from MMC2
> > Starting ATF on ARM64 core...
> >
> > NOTICE: BL31: v2.10.0(release):v2.10.0-729-gc8be7c08c
> > NOTICE: BL31: Built : 14:04:51, Jun 24 2024
> > I/TC:
> > I/TC: OP-TEE version: 4.2.0-22-g16fbd46d2 (gcc version 13.2.0 (GCC)) #4 Mon Jun 24 20:04:07 U
> > TC 2024 aarch64
> > I/TC: WARNING: This OP-TEE configuration might be insecure!
> > I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guide
> > lines.html
> > I/TC: Primary CPU initializing
> > I/TC: GIC redistributor base address not provided
> > I/TC: Assuming default GIC group status and modifier
> > I/TC: SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> > I/TC: HUK Initialized
> > I/TC: Primary CPU switching to normal world boot
> >
> > U-Boot SPL 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
> > SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
> > SPL initial stack usage: 2048 bytes
> > Trying to boot from MMC2
> >
> >
> > U-Boot 2026.04-rc1-00076-gfd070b0e7186 (Feb 03 2026 - 16:09:31 +0000)
> >
> > SoC: AM62X SR1.0 GP
> > Reset reason: POR
> > Model: BeagleBoard.org BeaglePlay
> > DRAM: 2 GiB
> > I/TC: Reserved shared memory is enabled
> > I/TC: Dynamic shared memory is enabled
> > I/TC: Normal World virtualization support is disabled
> > I/TC: Asynchronous notifications are disabled
> > Core: 112 devices, 33 uclasses, devicetree: separate
> > MMC: mmc@fa10000: 0, mmc@fa00000: 1, mmc@fa20000: 2
> > Loading Environment from nowhere... OK
> > In: serial@2800000
> > Out: serial@2800000
> > Err: serial@2800000
> > Net: "Synchronous Abort" handler, esr 0x02000000
> > elr: 00000000808c1b28 lr : 00000000808357b0 (reloc)
> > elr: 00000000fffd2b28 lr : 00000000fff467b0
> > x0 : 00000000fdef7340 x1 : 00000000fffd2b28
> > x2 : 000000000000000a x3 : 0000000000000000
> > x4 : 000000000000000d x5 : 0000000000000064
> > x6 : 00000000fffb088b x7 : 0000000000000044
> > x8 : 000000000000000a x9 : 0000000000000034
> > x10: 0000000000000002 x11: 00000000ffffffff
> > x12: 00000000fdede730 x13: 0000000000007040
> > x14: 00000000fdede730 x15: 00000000ffffffff
> > x16: 00000000fff53ac8 x17: 0000000000000000
> > x18: 00000000fdef1e10 x19: 0000000000000000
> > x20: 00000000fdef7340 x21: 00000000fffccfc0
> > x22: 00000000fffd4ed0 x23: 00000000fffd4000
> > x24: 00000000fdefac18 x25: 00000000fdefac18
> > x26: 00000000fff7bcfc x27: 00000000fff7bdb4
> > x28: 00000000fffaa8f0 x29: 00000000fdede5b0
> >
> > Code: fffd2b08 00000000 fffd2b08 00000000 (fffd2b18)
> > Resetting CPU ...
> >
> > resetting ...
> >
>
> Is the uboot image built by buildman toolchain or some other toolchain? I've
> tried to generate the image with `tools/buildman/buildman -M -k
> am62x_beagleplay_r5` and debug it with `gdb-multiarch
> ../current/am62x_beagleplay_r5/u-boot`. But the result doesn't seem correct.
>
>
> The output of gdb:
>
> (gdb) disas/r 0x808357b0
> Dump of assembler code for function menu_destroy.isra.0:
> 0x8083578c <+0>: b5f8 push {r3, r4, r5, r6, r7, lr}
> 0x8083578e <+2>: 4605 mov r5, r0
> 0x80835790 <+4>: 4604 mov r4, r0
> 0x80835792 <+6>: f855 3f24 ldr.w r3, [r5, #36]!
> 0x80835796 <+10>: 681e ldr r6, [r3, #0]
> 0x80835798 <+12>: 42ab cmp r3, r5
> 0x8083579a <+14>: d108 bne.n 0x808357ae
> <menu_destroy.isra.0+34>
> 0x8083579c <+16>: 68a0 ldr r0, [r4, #8]
> 0x8083579e <+18>: b108 cbz r0, 0x808357a4
> <menu_destroy.isra.0+24>
> 0x808357a0 <+20>: f7d6 fae6 bl 0x8080bd70 <free>
> 0x808357a4 <+24>: 4620 mov r0, r4
> 0x808357a6 <+26>: e8bd 40f8 ldmia.w sp!, {r3, r4, r5, r6, r7,
> lr}
> 0x808357aa <+30>: f7d6 bae1 b.w 0x8080bd70 <free>
> 0x808357ae <+34>: f853 0c08 ldr.w r0, [r3, #-8]
> 0x808357b2 <+38>: f1a3 0708 sub.w r7, r3, #8
> 0x808357b6 <+42>: b108 cbz r0, 0x808357bc
> <menu_destroy.isra.0+48>
> 0x808357b8 <+44>: f7d6 fada bl 0x8080bd70 <free>
> 0x808357bc <+48>: 4638 mov r0, r7
> 0x808357be <+50>: f7d6 fad7 bl 0x8080bd70 <free>
> 0x808357c2 <+54>: 4633 mov r3, r6
> 0x808357c4 <+56>: 6836 ldr r6, [r6, #0]
> 0x808357c6 <+58>: e7e7 b.n 0x80835798
> <menu_destroy.isra.0+12>
> End of assembler dump.
I can send you the binaries if needed, off-list. But the likely answer
is that we're on the a53 part of the system and not the r5 part of the
system at this point.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-02-09 14:23 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-19 19:07 [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 1/6] drivers: core: device: set new parent when old parent is NULL Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-01-19 19:07 ` [PATCH v3 2/6] test: dm: core: add some assertions for device_reparent() Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-01-19 19:07 ` [PATCH v3 3/6] clk: add uclass id check to clk_get_parent() Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 4/6] clk: use clk_get_parent() helper in clk_en(dis)able() Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 5/6] clk: allow assigning parent lazily Yang Xiwen via B4 Relay
2026-01-19 19:07 ` [PATCH v3 6/6] test: clk: add test for CLK_LAZY_REPARENT Yang Xiwen via B4 Relay
2026-02-04 0:23 ` Simon Glass
2026-02-02 20:17 ` [PATCH v3 0/6] clk: support arbitrary clk_register() sequence Tom Rini
2026-02-03 15:28 ` Yang Xiwen
2026-02-03 16:15 ` Tom Rini
2026-02-07 14:58 ` Yang Xiwen
2026-02-09 14:23 ` Tom Rini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox