Commit 75f98314f92f64fd3526464006d934d4fe9b2710

Authored by Jagan Teki
1 parent b24f9057e8

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>

Showing 2 changed files with 75 additions and 1 deletions Side-by-side Diff

drivers/clk/clk-uclass.c
... ... @@ -54,6 +54,46 @@
54 54 return 0;
55 55 }
56 56  
  57 +static int clk_get_by_index_tail(int ret, ofnode node,
  58 + struct ofnode_phandle_args *args,
  59 + const char *list_name, int index,
  60 + struct clk *clk)
  61 +{
  62 + struct udevice *dev_clk;
  63 + const struct clk_ops *ops;
  64 +
  65 + assert(clk);
  66 + clk->dev = NULL;
  67 + if (ret)
  68 + goto err;
  69 +
  70 + ret = uclass_get_device_by_ofnode(UCLASS_CLK, args->node, &dev_clk);
  71 + if (ret) {
  72 + debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
  73 + __func__, ret);
  74 + return ret;
  75 + }
  76 +
  77 + clk->dev = dev_clk;
  78 +
  79 + ops = clk_dev_ops(dev_clk);
  80 +
  81 + if (ops->of_xlate)
  82 + ret = ops->of_xlate(clk, args);
  83 + else
  84 + ret = clk_of_xlate_default(clk, args);
  85 + if (ret) {
  86 + debug("of_xlate() failed: %d\n", ret);
  87 + return ret;
  88 + }
  89 +
  90 + return clk_request(dev_clk, clk);
  91 +err:
  92 + debug("%s: Node '%s', property '%s', failed to request CLK index %d: %d\n",
  93 + __func__, ofnode_get_name(node), list_name, index, ret);
  94 + return ret;
  95 +}
  96 +
57 97 static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
58 98 int index, struct clk *clk)
59 99 {
... ... @@ -100,7 +140,26 @@
100 140  
101 141 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
102 142 {
103   - return clk_get_by_indexed_prop(dev, "clocks", index, clk);
  143 + struct ofnode_phandle_args args;
  144 + int ret;
  145 +
  146 + ret = dev_read_phandle_with_args(dev, "clocks", "#clock-cells", 0,
  147 + index, &args);
  148 +
  149 + return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks",
  150 + index > 0, clk);
  151 +}
  152 +
  153 +int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk)
  154 +{
  155 + struct ofnode_phandle_args args;
  156 + int ret;
  157 +
  158 + ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0,
  159 + index > 0, &args);
  160 +
  161 + return clk_get_by_index_tail(ret, node, &args, "clocks",
  162 + index > 0, clk);
104 163 }
105 164  
106 165 int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
... ... @@ -8,6 +8,7 @@
8 8 #ifndef _CLK_H_
9 9 #define _CLK_H_
10 10  
  11 +#include <dm/ofnode.h>
11 12 #include <linux/errno.h>
12 13 #include <linux/types.h>
13 14  
... ... @@ -99,6 +100,20 @@
99 100 * @return 0 if OK, or a negative error code.
100 101 */
101 102 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
  103 +
  104 +/**
  105 + * clock_get_by_index_nodev - Get/request a clock by integer index
  106 + * without a device.
  107 + *
  108 + * This is a version of clk_get_by_index() that does not use a device.
  109 + *
  110 + * @node: The client ofnode.
  111 + * @index: The index of the clock to request, within the client's list of
  112 + * clocks.
  113 + * @clock A pointer to a clock struct to initialize.
  114 + * @return 0 if OK, or a negative error code.
  115 + */
  116 +int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk);
102 117  
103 118 /**
104 119 * clock_get_bulk - Get/request all clocks of a device.