[U-Boot] [PATCH 2/3] clk: prograte clk enable/disable to parent
Peng Fan
peng.fan at nxp.com
Fri Aug 16 08:10:12 UTC 2019
When enabling/disabling a clk, also need to enable/disable
the clk's parent. Implement this in clk_enable/disable.
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
drivers/clk/clk-uclass.c | 68 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 62 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index cee4d912b0..208c9b7906 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -449,13 +449,41 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
int clk_enable(struct clk *clk)
{
const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ struct clk *clkp = NULL;
+ int ret;
debug("%s(clk=%p)\n", __func__, clk);
- if (!ops->enable)
- return -ENOSYS;
+ 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)) {
+ if (clkp->dev->parent &&
+ device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
+ if (ret) {
+ printf("Enable %s failed\n",
+ clkp->dev->parent->name);
+ return ret;
+ }
+ }
+ }
- return ops->enable(clk);
+ if (ops->enable) {
+ ret = ops->enable(clk);
+ if (ret) {
+ printf("Enable %s failed\n", clk->dev->name);
+ return ret;
+ }
+ }
+ if (clkp)
+ clkp->enable_cnt++;
+ } else {
+ if (!ops->enable)
+ return -ENOSYS;
+ return ops->enable(clk);
+ }
+
+ return 0;
}
int clk_enable_bulk(struct clk_bulk *bulk)
@@ -474,13 +502,41 @@ int clk_enable_bulk(struct clk_bulk *bulk)
int clk_disable(struct clk *clk)
{
const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ struct clk *clkp;
+ int ret;
debug("%s(clk=%p)\n", __func__, clk);
- if (!ops->disable)
- return -ENOSYS;
+ if (CONFIG_IS_ENABLED(CLK_CCF)) {
+ if (ops->disable) {
+ ret = ops->disable(clk);
+ if (ret)
+ return ret;
+ }
+
+ if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
+ if (clkp->dev->parent &&
+ device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
+ if (ret) {
+ printf("Disable %s failed\n",
+ clkp->dev->parent->name);
+ return ret;
+ }
+ }
+ }
+
+ if (clkp)
+ clkp->enable_cnt--;
+ } else {
- return ops->disable(clk);
+ if (!ops->disable)
+ return -ENOSYS;
+
+ return ops->disable(clk);
+ }
+
+ return 0;
}
int clk_disable_bulk(struct clk_bulk *bulk)
--
2.16.4
More information about the U-Boot
mailing list