rockchip: clock: Add a function to find a clock by ID
authorSimon Glass <sjg@chromium.org>
Fri, 22 Jan 2016 02:43:41 +0000 (19:43 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 22 Jan 2016 03:42:34 +0000 (20:42 -0700)
The current approach of using uclass_get_device() is error-prone. Another
clock (for example a fixed-clock) may cause it to break. Add a function that
does a proper search.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/arm/include/asm/arch-rockchip/clock.h
drivers/clk/clk_rk3288.c

index 8a0376c501ed117c1b6759b8a46f784d023da649..a9ea2689c7462bc3f6815bc59a89859eeb1b9377 100644 (file)
@@ -62,4 +62,16 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
  */
 void *rockchip_get_cru(void);
 
+/**
+ * rkclk_get_clk() - get a pointer to a given clock
+ *
+ * This is an internal function - use outside the clock subsystem indicates
+ * that work is needed!
+ *
+ * @clk_id:    Clock requested
+ * @devp:      Returns a pointer to that clock
+ * @return 0 if OK, -ve on error
+ */
+int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp);
+
 #endif
index df5c38cf7258ae81db79f149f416f8b1ea625df1..fdc5347d0a71752cf9529ba8af9e1ce255eabada 100644 (file)
@@ -15,7 +15,9 @@
 #include <asm/arch/grf_rk3288.h>
 #include <asm/arch/hardware.h>
 #include <dt-bindings/clock/rk3288-cru.h>
+#include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <dm/uclass-internal.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -139,6 +141,24 @@ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
 static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
 
+int rkclk_get_clk(enum rk_clk_id clk_id, struct udevice **devp)
+{
+       struct udevice *dev;
+
+       for (uclass_find_first_device(UCLASS_CLK, &dev);
+            dev;
+            uclass_find_next_device(&dev)) {
+               struct rk3288_clk_plat *plat = dev_get_platdata(dev);
+
+               if (plat->clk_id == clk_id) {
+                       *devp = dev;
+                       return device_probe(dev);
+               }
+       }
+
+       return -ENODEV;
+}
+
 static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
                         const struct pll_div *div)
 {
@@ -515,7 +535,7 @@ static ulong rk3288_get_periph_rate(struct udevice *dev, int periph)
        ulong new_rate, gclk_rate;
        int ret;
 
-       ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &gclk);
+       ret = rkclk_get_clk(CLK_GENERAL, &gclk);
        if (ret)
                return ret;
        gclk_rate = clk_get_rate(gclk);
@@ -551,7 +571,7 @@ static ulong rk3288_set_periph_rate(struct udevice *dev, int periph, ulong rate)
        ulong new_rate, gclk_rate;
        int ret;
 
-       ret = uclass_get_device(UCLASS_CLK, CLK_GENERAL, &gclk);
+       ret = rkclk_get_clk(CLK_GENERAL, &gclk);
        if (ret)
                return ret;
        gclk_rate = clk_get_rate(gclk);