[U-Boot,v2,48/53] clk: Get the CLK by index without device

Message ID 20180810060711.6547-49-jagan@amarulasolutions.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show
Series
  • clk: Add Allwinner CLK, RESET support
Related show

Commit Message

Jagan Teki Aug. 10, 2018, 6:07 a.m.
Getting a CLK by index with device is not straight forward
for some use-cases like handling clock operations for child
node in parent driver. So we need to process the child node
in parent probe via ofnode and process CLK operation for child
without udevice but with ofnode.

So add clk_get_by_index_nodev() and move the common code
in clk_get_by_index_tail() to use for clk_get_by_index()

Cc: Simon Glass <sjg@chromium.org>
Cc: Joe Hershberger <joe.hershberger@ni.com>
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
 drivers/clk/clk-uclass.c | 61 +++++++++++++++++++++++++++++++++++++++-
 include/clk.h            | 15 ++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)

Patch

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 2b15978e14..8bb41a4de5 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -98,9 +98,68 @@  static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
 	return clk_request(dev_clk, clk);
 }
 
+static int clk_get_by_index_tail(int ret, ofnode node,
+				 struct ofnode_phandle_args *args,
+				 const char *list_name, int index,
+				 struct clk *clk)
+{
+	struct udevice *dev_clk;
+	const struct clk_ops *ops;
+
+	assert(clk);
+	clk->dev = NULL;
+	if (ret)
+		goto err;
+
+	ret = uclass_get_device_by_ofnode(UCLASS_CLK, args->node, &dev_clk);
+	if (ret) {
+		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
+		      __func__, ret);
+		return ret;
+	}
+
+	clk->dev = dev_clk;
+
+	ops = clk_dev_ops(dev_clk);
+
+	if (ops->of_xlate)
+		ret = ops->of_xlate(clk, args);
+	else
+		ret = clk_of_xlate_default(clk, args);
+	if (ret) {
+		debug("of_xlate() failed: %d\n", ret);
+		return ret;
+	}
+
+	return clk_request(dev_clk, clk);
+err:
+	debug("%s: Node '%s', property '%s', failed to request CLK index %d: %d\n",
+	       __func__, ofnode_get_name(node), list_name, index, ret);
+	return ret;
+}
+
 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
 {
-	return clk_get_by_indexed_prop(dev, "clocks", index, clk);
+	struct ofnode_phandle_args args;
+	int ret;
+
+	ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
+					 index, &args);
+
+	return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks",
+				     index > 0, clk);
+}
+
+int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk)
+{
+	struct ofnode_phandle_args args;
+	int ret;
+
+	ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0,
+					     index > 0, &args);
+
+	return clk_get_by_index_tail(ret, node, &args, "clocks",
+				     index > 0, clk);
 }
 
 int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
diff --git a/include/clk.h b/include/clk.h
index f6d1cc53a1..1d8478f061 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -8,6 +8,7 @@ 
 #ifndef _CLK_H_
 #define _CLK_H_
 
+#include <dm/ofnode.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 
@@ -98,6 +99,20 @@  int clk_get_by_index_platdata(struct udevice *dev, int index,
  */
 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
 
+/**
+ * clock_get_by_index_nodev - Get/request a clock by integer index
+ * without a device.
+ *
+ * This is a version of clk_get_by_index() that does not use a device.
+ *
+ * @node:	The client ofnode.
+ * @index:	The index of the clock to request, within the client's list of
+ *		clocks.
+ * @clock	A pointer to a clock struct to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk);
+
 /**
  * clock_get_bulk - Get/request all clocks of a device.
  *