From 09844d0de5550e7f91246031220074a80b5a821a Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Sat, 11 Nov 2023 03:19:52 +0800 Subject: clk: check parent_name in clk_register to avoid confusing log_error() output For some gate clocks and fixed clocks without a parent, calling clk_register will print an useless error message indicating that parent is missing. Fix that by gaurding log_xxx() with an if-statement. Signed-off-by: Yang Xiwen Suggested-by: Sean Anderson Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20230807-clk-fix-v2-1-0b688e21fb4e@outlook.com --- drivers/clk/clk.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index a5a3461b66c..6ede1b4d4dc 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -18,17 +18,19 @@ int clk_register(struct clk *clk, const char *drv_name, const char *name, const char *parent_name) { - struct udevice *parent; + struct udevice *parent = NULL; struct driver *drv; int ret; - 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); - } else { - log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, - parent->name, parent); + 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); + } else { + log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, + parent->name, parent); + } } drv = lists_driver_lookup_name(drv_name); -- cgit v1.2.3 From 3fb2d3d6acbaad50d2e638f6abb4e9d7a511c462 Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Sun, 19 Nov 2023 06:10:06 +0800 Subject: clk: get correct ops for clk_enable() and clk_disable() assign clk_dev_ops(clkp->dev) to ops to ensure correct clk operations are called on clocks. This fixes the incorrect enable_count issue as described in [1]. [1]: https://lore.kernel.org/all/SEZPR06MB695927A6DEEEF8489A06897396A7A@SEZPR06MB6959.apcprd06.prod.outlook.com/ Signed-off-by: Yang Xiwen Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20231111-enable_count-v2-2-20e3728600b5@outlook.com --- drivers/clk/clk-uclass.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 3b5e3f9c86b..3e9d68feb3c 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -640,6 +640,7 @@ int clk_enable(struct clk *clk) if (CONFIG_IS_ENABLED(CLK_CCF)) { /* Take id 0 as a non-valid clk, such as dummy */ if (clk->id && !clk_get_by_id(clk->id, &clkp)) { + ops = clk_dev_ops(clkp->dev); if (clkp->enable_count) { clkp->enable_count++; return 0; @@ -699,6 +700,7 @@ int clk_disable(struct clk *clk) if (CONFIG_IS_ENABLED(CLK_CCF)) { if (clk->id && !clk_get_by_id(clk->id, &clkp)) { + ops = clk_dev_ops(clkp->dev); if (clkp->flags & CLK_IS_CRITICAL) return 0; -- cgit v1.2.3 From 54d7da77306257a03231b04e7f2f9393ad7b0e46 Mon Sep 17 00:00:00 2001 From: Igor Prusov Date: Wed, 6 Dec 2023 02:23:33 +0300 Subject: clk: Check that composite clock's div has set_rate() It's possible for composite clocks to have a divider that does not implement set_rate() operation. For example, sandbox_clk_composite() registers composite clock with a divider that only has get_rate(). Currently clk_composite_set_rate() only checks thate rate_ops are present, so for sandbox it will cause NULL dereference during clk_set_rate(). This patch adds rate_ops->set_rate check tp clk_composite_set_rate(). Signed-off-by: Igor Prusov Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20231205232334.2931-2-ivprusov@salutedevices.com --- drivers/clk/clk-composite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 6eb2b8133a3..d2e5a1ae401 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -66,7 +66,7 @@ static ulong clk_composite_set_rate(struct clk *clk, unsigned long rate) const struct clk_ops *rate_ops = composite->rate_ops; struct clk *clk_rate = composite->rate; - if (rate && rate_ops) + if (rate && rate_ops && rate_ops->set_rate) return rate_ops->set_rate(clk_rate, rate); else return clk_get_rate(clk); -- cgit v1.2.3 From 9e0250321a0d7c7b17fcbac172dd3d3c000ee53a Mon Sep 17 00:00:00 2001 From: Igor Prusov Date: Wed, 6 Dec 2023 02:23:34 +0300 Subject: dm: test: clk: Add test for ccf clk_set_rate() Add a simple test case which sets clock rate to its current value. Signed-off-by: Igor Prusov Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20231205232334.2931-3-ivprusov@salutedevices.com --- test/dm/clk_ccf.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c index e4ebb93cdad..3b239825414 100644 --- a/test/dm/clk_ccf.c +++ b/test/dm/clk_ccf.c @@ -63,6 +63,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) rate = clk_get_parent_rate(clk); ut_asserteq(rate, 60000000); + rate = clk_set_rate(clk, 60000000); + ut_asserteq(rate, -ENOSYS); + rate = clk_get_rate(clk); ut_asserteq(rate, 60000000); @@ -87,6 +90,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) ut_asserteq_str("pll3_80m", pclk->dev->name); ut_asserteq(CLK_SET_RATE_PARENT, pclk->flags); + rate = clk_set_rate(clk, 80000000); + ut_asserteq(rate, -ENOSYS); + rate = clk_get_rate(clk); ut_asserteq(rate, 80000000); @@ -108,6 +114,9 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) rate = clk_get_rate(clk); ut_asserteq(rate, 60000000); + rate = clk_set_rate(clk, 60000000); + ut_asserteq(rate, 60000000); + #if CONFIG_IS_ENABLED(CLK_CCF) /* Test clk tree enable/disable */ ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk); -- cgit v1.2.3 From d30618243990457d219ab81955c2738580d26cd2 Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Sat, 16 Dec 2023 02:28:52 +0800 Subject: test: dm: clk_ccf: test ccf_clk_ops Assign ccf_clk_ops to .ops of clk_ccf driver so that it can act as an clk provider. Also add "#clock-cells=<1>" to its device tree node. Add "i2c_root" to clk_test in the device tree and driver for testing. Get "i2c_root" clock in CCF unit tests and add tests for it. Signed-off-by: Yang Xiwen Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20231111-enable_count-v3-2-08a821892fa9@outlook.com --- arch/sandbox/dts/test.dts | 4 +++- arch/sandbox/include/asm/clk.h | 1 + drivers/clk/clk_sandbox_ccf.c | 1 + drivers/clk/clk_sandbox_test.c | 1 + test/dm/clk_ccf.c | 14 +++++++++++--- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c7197795efb..a3a865d65ca 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -631,9 +631,10 @@ clocks = <&clk_fixed>, <&clk_sandbox 1>, <&clk_sandbox 0>, + <&ccf 11>, <&clk_sandbox 3>, <&clk_sandbox 2>; - clock-names = "fixed", "i2c", "spi", "uart2", "uart1"; + clock-names = "fixed", "i2c", "spi", "i2c_root", "uart2", "uart1"; }; clk-test2 { @@ -654,6 +655,7 @@ ccf: clk-ccf { compatible = "sandbox,clk-ccf"; + #clock-cells = <1>; }; efi-media { diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index df7156fe317..1daf2e7ac79 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -39,6 +39,7 @@ enum sandbox_clk_test_id { SANDBOX_CLK_TEST_ID_FIXED, SANDBOX_CLK_TEST_ID_SPI, SANDBOX_CLK_TEST_ID_I2C, + SANDBOX_CLK_TEST_ID_I2C_ROOT, SANDBOX_CLK_TEST_ID_DEVM1, SANDBOX_CLK_TEST_ID_DEVM2, SANDBOX_CLK_TEST_ID_DEVM_NULL, diff --git a/drivers/clk/clk_sandbox_ccf.c b/drivers/clk/clk_sandbox_ccf.c index fedcdd40448..38184e27aa4 100644 --- a/drivers/clk/clk_sandbox_ccf.c +++ b/drivers/clk/clk_sandbox_ccf.c @@ -284,6 +284,7 @@ static int sandbox_clk_ccf_probe(struct udevice *dev) U_BOOT_DRIVER(sandbox_clk_ccf) = { .name = "sandbox_clk_ccf", .id = UCLASS_CLK, + .ops = &ccf_clk_ops, .probe = sandbox_clk_ccf_probe, .of_match = sandbox_clk_ccf_test_ids, }; diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index 5807a454f3b..c695b69321e 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -15,6 +15,7 @@ static const char * const sandbox_clk_test_names[] = { [SANDBOX_CLK_TEST_ID_FIXED] = "fixed", [SANDBOX_CLK_TEST_ID_SPI] = "spi", [SANDBOX_CLK_TEST_ID_I2C] = "i2c", + [SANDBOX_CLK_TEST_ID_I2C_ROOT] = "i2c_root", }; int sandbox_clk_test_get(struct udevice *dev) diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c index 3b239825414..99481877a8f 100644 --- a/test/dm/clk_ccf.c +++ b/test/dm/clk_ccf.c @@ -18,8 +18,8 @@ /* Tests for Common Clock Framework driver */ static int dm_test_clk_ccf(struct unit_test_state *uts) { - struct clk *clk, *pclk; - struct udevice *dev; + struct clk *clk, *pclk, clk_ccf; + struct udevice *dev, *test_dev; long long rate; int ret; #if CONFIG_IS_ENABLED(CLK_CCF) @@ -29,6 +29,7 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) /* Get the device using the clk device */ ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "clk-test", &test_dev)); /* Test for clk_get_by_id() */ ret = clk_get_by_id(SANDBOX_CLK_ECSPI_ROOT, &clk); @@ -119,11 +120,18 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) #if CONFIG_IS_ENABLED(CLK_CCF) /* Test clk tree enable/disable */ + + 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_asserteq(clk_ccf.id, SANDBOX_CLK_I2C_ROOT); + ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk); ut_assertok(ret); ut_asserteq_str("i2c_root", clk->dev->name); + ut_asserteq(clk->id, SANDBOX_CLK_I2C_ROOT); - ret = clk_enable(clk); + ret = clk_enable(&clk_ccf); ut_assertok(ret); ret = sandbox_clk_enable_count(clk); -- cgit v1.2.3 From 97d65b32d76cb3b8297cd8aa2c1f0caab5ab6c57 Mon Sep 17 00:00:00 2001 From: Yang Xiwen Date: Sat, 16 Dec 2023 04:21:11 +0800 Subject: test: dm: clk_ccf: fix building error Fix unused variable error produced by building tests Fixes: d3061824 (test: dm: clk_ccf: test ccf_clk_ops) Signed-off-by: Yang Xiwen Reviewed-by: Sean Anderson Link: https://lore.kernel.org/r/20231216-b4-fix_build-v1-1-b8e79c94744f@outlook.com --- test/dm/clk_ccf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/dm/clk_ccf.c b/test/dm/clk_ccf.c index 99481877a8f..61dad8d8527 100644 --- a/test/dm/clk_ccf.c +++ b/test/dm/clk_ccf.c @@ -18,11 +18,12 @@ /* Tests for Common Clock Framework driver */ static int dm_test_clk_ccf(struct unit_test_state *uts) { - struct clk *clk, *pclk, clk_ccf; + struct clk *clk, *pclk; struct udevice *dev, *test_dev; long long rate; int ret; #if CONFIG_IS_ENABLED(CLK_CCF) + struct clk clk_ccf; const char *clkname; int clkid, i; #endif -- cgit v1.2.3