clk: bind clk to new parent device

Clock re-parenting is not binding the clock's device to its new
parent device, it only calls the clock's ops->set_parent() API. The
changes in this commit re-parent the clock device to its new parent
so that subsequent operations like clk_get_parent() to point to the
proper parent.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Claudiu Beznea 2020-09-07 17:46:34 +03:00 committed by Eugen Hristev
parent cfecbaf4e7
commit 4d139f3838
2 changed files with 37 additions and 1 deletions

View File

@ -14,6 +14,7 @@
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <dm/device-internal.h>
#include <dm/devres.h>
#include <dm/read.h>
#include <linux/bug.h>
@ -512,6 +513,7 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
int clk_set_parent(struct clk *clk, struct clk *parent)
{
const struct clk_ops *ops;
int ret;
debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);
if (!clk_valid(clk))
@ -521,7 +523,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
if (!ops->set_parent)
return -ENOSYS;
return ops->set_parent(clk, parent);
ret = ops->set_parent(clk, parent);
if (ret)
return ret;
if (CONFIG_IS_ENABLED(CLK_CCF))
ret = device_reparent(clk->dev, parent->dev);
return ret;
}
int clk_enable(struct clk *clk)

View File

@ -22,6 +22,10 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
struct udevice *dev;
long long rate;
int ret;
#if CONFIG_IS_ENABLED(CLK_CCF)
const char *clkname;
int clkid;
#endif
/* Get the device using the clk device */
ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev));
@ -130,6 +134,29 @@ static int dm_test_clk_ccf(struct unit_test_state *uts)
ret = sandbox_clk_enable_count(pclk);
ut_asserteq(ret, 0);
/* Test clock re-parenting. */
ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, &clk);
ut_assertok(ret);
ut_asserteq_str("usdhc1_sel", clk->dev->name);
pclk = clk_get_parent(clk);
ut_assertok_ptr(pclk);
if (!strcmp(pclk->dev->name, "pll3_60m")) {
clkname = "pll3_80m";
clkid = SANDBOX_CLK_PLL3_80M;
} else {
clkname = "pll3_60m";
clkid = SANDBOX_CLK_PLL3_60M;
}
ret = clk_get_by_id(clkid, &pclk);
ut_assertok(ret);
ret = clk_set_parent(clk, pclk);
ut_assertok(ret);
pclk = clk_get_parent(clk);
ut_assertok_ptr(pclk);
ut_asserteq_str(clkname, pclk->dev->name);
#endif
return 1;