]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
clk: ccf: mux: change the get_rate helper
authorDario Binacchi <dariobin@libero.it>
Wed, 3 Jun 2020 13:36:25 +0000 (15:36 +0200)
committerLukasz Majewski <lukma@denx.de>
Mon, 24 Aug 2020 09:03:26 +0000 (11:03 +0200)
The previous version of the get_rate helper does not work if the mux
clock parent is changed after the probe. This error has not been
detected because this condition has not been tested. The error occurs
because the set_parent helper does not change the parent of the clock
device but only the clock selection register. Since changing the parent
of a probed device can be tricky, the new version of the get_rate helper
provides the rate of the selected clock and not that of the parent.

Signed-off-by: Dario Binacchi <dariobin@libero.it>
drivers/clk/clk-mux.c
test/dm/clk_ccf.c

index e10baaf83b4704e4a52004293c3847701ee819be..ec8017b7d2fcf1d4fec05b6b6420ad60409088bd 100644 (file)
@@ -149,8 +149,32 @@ static int clk_mux_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
+static ulong clk_mux_get_rate(struct clk *clk)
+{
+       struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ?
+                       dev_get_clk_ptr(clk->dev) : clk);
+       struct udevice *parent;
+       struct clk *pclk;
+       int err, index;
+
+       index = clk_mux_get_parent(clk);
+       if (index >= mux->num_parents)
+               return -EFAULT;
+
+       err = uclass_get_device_by_name(UCLASS_CLK, mux->parent_names[index],
+                                       &parent);
+       if (err)
+               return err;
+
+       pclk = dev_get_clk_ptr(parent);
+       if (!pclk)
+               return -ENODEV;
+
+       return clk_get_rate(pclk);
+}
+
 const struct clk_ops clk_mux_ops = {
-       .get_rate = clk_generic_get_rate,
+       .get_rate = clk_mux_get_rate,
        .set_parent = clk_mux_set_parent,
 };
 
index 242d2d756fd75fd9a3127b9fec294d2d560531a1..32bc4d2b8a0ce173b321c72bc0543ebffac1d362 100644 (file)
@@ -59,6 +59,18 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
        rate = clk_get_parent_rate(clk);
        ut_asserteq(rate, 60000000);
 
+       rate = clk_get_rate(clk);
+       ut_asserteq(rate, 60000000);
+
+       ret = clk_get_by_id(SANDBOX_CLK_PLL3_80M, &pclk);
+       ut_assertok(ret);
+
+       ret = clk_set_parent(clk, pclk);
+       ut_assertok(ret);
+
+       rate = clk_get_rate(clk);
+       ut_asserteq(rate, 80000000);
+
        ret = clk_get_by_id(SANDBOX_CLK_USDHC2_SEL, &clk);
        ut_assertok(ret);
        ut_asserteq_str("usdhc2_sel", clk->dev->name);
@@ -71,6 +83,18 @@ 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_get_rate(clk);
+       ut_asserteq(rate, 80000000);
+
+       ret = clk_get_by_id(SANDBOX_CLK_PLL3_60M, &pclk);
+       ut_assertok(ret);
+
+       ret = clk_set_parent(clk, pclk);
+       ut_assertok(ret);
+
+       rate = clk_get_rate(clk);
+       ut_asserteq(rate, 60000000);
+
        /* Test the composite of CCF */
        ret = clk_get_by_id(SANDBOX_CLK_I2C, &clk);
        ut_assertok(ret);