This commit adds the clk_get_parent_rate() function, which is responsible
for getting the rate of parent clock.
Unfortunately, u-boot's DM support for getting parent is different
(the parent relationship is in udevice) than the one in common clock
framework (CCF) in Linux.

To alleviate this problem - the clk_get_parent_rate() function has been
introduced to clk-uclass.c.

As written in the in-code comment - some clocks do not set clk->id (and
require it to be set to 0) and hence the standard ckl_{request|get_rate|
free} API is used.

Signed-off-by: Lukasz Majewski <lu...@denx.de>
---

Changes in v2: None

 drivers/clk/clk-uclass.c | 41 +++++++++++++++++++++++++++++++++++++++++
 include/clk.h            |  9 +++++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 6d7a514006..f1640dda67 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -340,6 +340,47 @@ ulong clk_get_rate(struct clk *clk)
        return ops->get_rate(clk);
 }
 
+ulong clk_get_parent_rate(struct clk *clk)
+{
+       const struct clk_ops *ops;
+       struct udevice *pdev;
+       struct clk pclk;
+       ulong rate;
+       int ret;
+
+       debug("%s(clk=%p)\n", __func__, clk);
+
+       pdev = clk->dev->parent;
+       if (!pdev)
+               return -ENODEV;
+
+       ops = clk_dev_ops(pdev);
+       if (!ops->get_rate)
+               return -ENOSYS;
+
+       /*
+        * We do use memset, clk_{request|get_rate|free}
+        * as there are clocks - like the "fixed" ones, which
+        * doesn't posses the clk wrapper struct (just added to
+        * UCLASS_CLK) and explicitly check if clk->id = 0.
+        *
+        * In fact the "clock" resources (like ops, description)
+        * are accessed via udevice structure (pdev - parent's one)
+        */
+
+       memset(&pclk, 0, sizeof(pclk));
+       ret = clk_request(pdev, &pclk);
+       if (ret) {
+               printf("%s: pclk: %s request failed!\n", __func__, pdev->name);
+               return ret;
+       }
+
+       rate = clk_get_rate(&pclk);
+       clk_free(&pclk);
+
+       return rate;
+}
+
 ulong clk_set_rate(struct clk *clk, ulong rate)
 {
        const struct clk_ops *ops = clk_dev_ops(clk->dev);
diff --git a/include/clk.h b/include/clk.h
index f6fbcc6634..8224295ec3 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -238,6 +238,15 @@ int clk_free(struct clk *clk);
 ulong clk_get_rate(struct clk *clk);
 
 /**
+ * clk_get_parent_rate() - Get parent of current clock rate.
+ *
+ * @clk:       A clock struct that was previously successfully requested by
+ *             clk_request/get_by_*().
+ * @return clock rate in Hz, or -ve error code.
+ */
+ulong clk_get_parent_rate(struct clk *clk);
+
+/**
  * clk_set_rate() - Set current clock rate.
  *
  * @clk:       A clock struct that was previously successfully requested by
-- 
2.11.0

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to