dm: clk: Define clk_get_parent_rate() for clk operations
[oweals/u-boot.git] / drivers / clk / clk-uclass.c
index 79b3b0494c652c947ef9b114ebb48a97154b650f..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)
 {
@@ -379,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);