mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-06 11:43:45 +00:00
clk: Propagate clk_set_rate() if CLK_SET_PARENT_RATE present
Sometimes clocks provided to a consumer might not have .set_rate operation (like gate or mux clocks), but have CLK_SET_PARENT_RATE flag set. In that case it's usually possible to find a parent up the tree which is capable of setting the rate (div, pll, etc). Implement a simple lookup procedure for such cases, to traverse the clock tree until .set_rate capable parent is found, and use that parent to actually change the rate. The search will stop once the first .set_rate capable clock is found, which is usually enough to handle most cases. Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
This commit is contained in:
parent
9bc62c980d
commit
e5aef1bbf1
1 changed files with 14 additions and 2 deletions
|
@ -569,9 +569,21 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
|
||||||
return 0;
|
return 0;
|
||||||
ops = clk_dev_ops(clk->dev);
|
ops = clk_dev_ops(clk->dev);
|
||||||
|
|
||||||
if (!ops->set_rate)
|
/* Try to find parents which can set rate */
|
||||||
|
while (!ops->set_rate) {
|
||||||
|
struct clk *parent;
|
||||||
|
|
||||||
|
if (!(clk->flags & CLK_SET_RATE_PARENT))
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
|
parent = clk_get_parent(clk);
|
||||||
|
if (IS_ERR_OR_NULL(parent) || !clk_valid(parent))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
clk = parent;
|
||||||
|
ops = clk_dev_ops(clk->dev);
|
||||||
|
}
|
||||||
|
|
||||||
/* get private clock struct used for cache */
|
/* get private clock struct used for cache */
|
||||||
clk_get_priv(clk, &clkp);
|
clk_get_priv(clk, &clkp);
|
||||||
/* Clean up cached rates for us and all child clocks */
|
/* Clean up cached rates for us and all child clocks */
|
||||||
|
|
Loading…
Add table
Reference in a new issue