summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/clk-uclass.c61
-rw-r--r--include/clk.h15
2 files changed, 75 insertions, 1 deletions
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 844b87cc33..d9236c5b51 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -54,6 +54,46 @@ static int clk_of_xlate_default(struct clk *clk,
return 0;
}
+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;
+}
+
static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
int index, struct clk *clk)
{
@@ -100,7 +140,26 @@ static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
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 8e366163f9..d24e99713a 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>
@@ -101,6 +102,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.
*
* This looks up and requests all clocks of the client device; each device is