[U-Boot] [PATCH v2 03/17] dm: clk: Define clk_get_parent_rate() for clk operations

Lukasz Majewski lukma at denx.de
Thu Jan 31 09:03:21 UTC 2019


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 <lukma at 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



More information about the U-Boot mailing list