clk: add APIs to get (optional) clock by name without a device
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Thu, 9 Jan 2020 03:35:07 +0000 (11:35 +0800)
committerTom Rini <trini@konsulko.com>
Thu, 16 Jan 2020 14:39:45 +0000 (09:39 -0500)
Sometimes we may need get (optional) clock without a device,
that means use ofnode.
e.g. when the phy node has subnode, and there is no device created
for subnode, in this case, we need these new APIs to get subnode's
clock.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Ryder Lee <ryder.lee@mediatek.com>
drivers/clk/clk-uclass.c
include/clk.h

index b7e18668cbd9a574d4fb078936039f4b3b07f8d3..93cb490eb5372b8eb5aa094288e979144ab5c047 100644 (file)
@@ -344,6 +344,34 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
        return clk_get_by_index(dev, index, clk);
 }
 
+int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
+{
+       int index;
+
+       debug("%s(node=%p, name=%s, clk=%p)\n", __func__,
+               ofnode_get_name(node), name, clk);
+       clk->dev = NULL;
+
+       index = ofnode_stringlist_search(node, "clock-names", name);
+       if (index < 0) {
+               debug("fdt_stringlist_search() failed: %d\n", index);
+               return index;
+       }
+
+       return clk_get_by_index_nodev(node, index, clk);
+}
+
+int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
+{
+       int ret;
+
+       ret = clk_get_by_name_nodev(node, name, clk);
+       if (ret == -ENODATA)
+               return 0;
+
+       return ret;
+}
+
 int clk_release_all(struct clk *clk, int count)
 {
        int i, ret;
index a5ee53d94aa4f60c62bccf442dbf319e81c5c75b..3336301815ff63a1513c09d20578631fbcf41399 100644 (file)
@@ -154,6 +154,34 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
  */
 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
 
+/**
+ * clk_get_by_name_nodev - Get/request a clock by name without a device.
+ *
+ * This is a version of clk_get_by_name() that does not use a device.
+ *
+ * @node:      The client ofnode.
+ * @name:      The name 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_name_nodev(ofnode node, const char *name, struct clk *clk);
+
+/**
+ * clock_get_optional_nodev - Get/request an optinonal clock by name
+ *             without a device.
+ * @node:      The client ofnode.
+ * @name:      The name of the clock to request.
+ * @name:      The name of the clock to request, within the client's list of
+ *             clocks.
+ * @clock:     A pointer to a clock struct to initialize.
+ *
+ * Behaves the same as clk_get_by_name_nodev() except where there is
+ * no clock producer, in this case, skip the error number -ENODATA, and
+ * the function returns 0.
+ */
+int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk);
+
 /**
  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -230,6 +258,18 @@ static inline int clk_get_by_name(struct udevice *dev, const char *name,
        return -ENOSYS;
 }
 
+static inline int
+clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
+{
+       return -ENOSYS;
+}
+
+static inline int
+clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
+{
+       return -ENOSYS;
+}
+
 static inline int clk_release_all(struct clk *clk, int count)
 {
        return -ENOSYS;