#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>
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))
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)
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));
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;