summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorJagan Teki <jagan@amarulasolutions.com>2019-02-28 00:26:52 +0530
committerJagan Teki <jagan@amarulasolutions.com>2019-05-09 00:44:13 +0530
commit75f98314f92f64fd3526464006d934d4fe9b2710 (patch)
tree3985d971f43df769093a3461e7dfb43c27893043 /drivers/clk
parentb24f9057e8a1c2e26acd3bdc2ba933cf9979b375 (diff)
clk: Get the CLK by index without device
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: Stephen Warren <swarren@nvidia.com> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/clk-uclass.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 844b87cc337..d9236c5b510 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)