dm: clk: Define clk_get_parent_rate() for clk operations
[oweals/u-boot.git] / drivers / clk / clk-uclass.c
index d9236c5b510490fc1eea5bb70d8c05d74729f94e..899b2dda6f318e26d865fdfc60288e6ff5c356ec 100644 (file)
@@ -13,6 +13,7 @@
 #include <dm/read.h>
 #include <dt-structs.h>
 #include <errno.h>
+#include <linux/clk-provider.h>
 
 static inline const struct clk_ops *clk_dev_ops(struct udevice *dev)
 {
@@ -99,8 +100,6 @@ static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
 {
        int ret;
        struct ofnode_phandle_args args;
-       struct udevice *dev_clk;
-       const struct clk_ops *ops;
 
        debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);
 
@@ -115,27 +114,9 @@ static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
                return ret;
        }
 
-       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);
+       return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks",
+                                    index > 0, clk);
 }
 
 int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
@@ -399,6 +380,43 @@ ulong clk_get_rate(struct clk *clk)
        return ops->get_rate(clk);
 }
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+       struct udevice *pdev;
+       struct clk *pclk;
+
+       debug("%s(clk=%p)\n", __func__, clk);
+
+       pdev = dev_get_parent(clk->dev);
+       pclk = dev_get_clk_ptr(pdev);
+       if (!pclk)
+               return ERR_PTR(-ENODEV);
+
+       return pclk;
+}
+
+long long clk_get_parent_rate(struct clk *clk)
+{
+       const struct clk_ops *ops;
+       struct clk *pclk;
+
+       debug("%s(clk=%p)\n", __func__, clk);
+
+       pclk = clk_get_parent(clk);
+       if (IS_ERR(pclk))
+               return -ENODEV;
+
+       ops = clk_dev_ops(pclk->dev);
+       if (!ops->get_rate)
+               return -ENOSYS;
+
+       /* Read the 'rate' if not already set */
+       if (!pclk->rate)
+               pclk->rate = clk_get_rate(pclk);
+
+       return pclk->rate;
+}
+
 ulong clk_set_rate(struct clk *clk, ulong rate)
 {
        const struct clk_ops *ops = clk_dev_ops(clk->dev);