]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ARM: i.MX5: Allow DT clock providers
authorMartin Fuzzey <mfuzzey@parkeon.com>
Tue, 23 Apr 2013 12:16:59 +0000 (20:16 +0800)
committerShawn Guo <shawn.guo@linaro.org>
Mon, 17 Jun 2013 07:45:09 +0000 (15:45 +0800)
Currently clock providers defined in the DT are not registered
on i.MX5 platforms since of_clk_init() is not called.

This is not a problem for the SOC's own clocks, which are registered
in code,  but prevents the DT being used to define clocks for external
hardware.

Fix this by calling of_clk_init() and actually using the DT to obtain
the 4 SOC fixed clocks.
These are already defined in the DT but were previously just used to
manually obtain the rate.

Fall back to the old scheme for non DT platforms.

Since the same method may be useful for other i.MX platforms
implement the imx_obtain_fixed_clock() function in common code.

Actually changing other i.MX platforms to use this should be done
later by someone with access to the appropriate hardware.

Signed-off-by: Martin Fuzzey <mfuzzey@parkeon.com>
Tested-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
arch/arm/mach-imx/clk-imx51-imx53.c
arch/arm/mach-imx/clk.c
arch/arm/mach-imx/clk.h

index 6fc486b6a3c68f7a5bd6a5457680cd895f41dc76..929762742ee123c49998098bc1c25cf820e80816 100644 (file)
@@ -123,11 +123,13 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 {
        int i;
 
+       of_clk_init(NULL);
+
        clk[dummy] = imx_clk_fixed("dummy", 0);
-       clk[ckil] = imx_clk_fixed("ckil", rate_ckil);
-       clk[osc] = imx_clk_fixed("osc", rate_osc);
-       clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1);
-       clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2);
+       clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
+       clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
+       clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1);
+       clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2);
 
        clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
                                lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
@@ -542,42 +544,12 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
        return 0;
 }
 
-#ifdef CONFIG_OF
-static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
-                                  unsigned long *ckih1, unsigned long *ckih2)
-{
-       struct device_node *np;
-
-       /* retrieve the freqency of fixed clocks from device tree */
-       for_each_compatible_node(np, NULL, "fixed-clock") {
-               u32 rate;
-               if (of_property_read_u32(np, "clock-frequency", &rate))
-                       continue;
-
-               if (of_device_is_compatible(np, "fsl,imx-ckil"))
-                       *ckil = rate;
-               else if (of_device_is_compatible(np, "fsl,imx-osc"))
-                       *osc = rate;
-               else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
-                       *ckih1 = rate;
-               else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
-                       *ckih2 = rate;
-       }
-}
-
 int __init mx51_clocks_init_dt(void)
 {
-       unsigned long ckil, osc, ckih1, ckih2;
-
-       clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
-       return mx51_clocks_init(ckil, osc, ckih1, ckih2);
+       return mx51_clocks_init(0, 0, 0, 0);
 }
 
 int __init mx53_clocks_init_dt(void)
 {
-       unsigned long ckil, osc, ckih1, ckih2;
-
-       clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
-       return mx53_clocks_init(ckil, osc, ckih1, ckih2);
+       return mx53_clocks_init(0, 0, 0, 0);
 }
-#endif
index 37e884ed1cd4098d43788e34e7f21d7d1ff88404..53e8788b0d0f21a7f7e40ceb763e7e417333461a 100644 (file)
@@ -1,4 +1,39 @@
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/slab.h>
 #include <linux/spinlock.h>
 #include "clk.h"
 
 DEFINE_SPINLOCK(imx_ccm_lock);
+
+static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
+{
+       struct of_phandle_args phandle = {0};
+       struct clk *clk = ERR_PTR(-ENODEV);
+       char *path;
+
+       path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
+       if (!path)
+               return ERR_PTR(-ENOMEM);
+
+       phandle.np = of_find_node_by_path(path);
+       kfree(path);
+
+       if (phandle.np) {
+               clk = of_clk_get_from_provider(&phandle);
+               of_node_put(phandle.np);
+       }
+       return clk;
+}
+
+struct clk * __init imx_obtain_fixed_clock(
+                       const char *name, unsigned long rate)
+{
+       struct clk *clk;
+
+       clk = imx_obtain_fixed_clock_from_dt(name);
+       if (IS_ERR(clk))
+               clk = imx_clk_fixed(name, rate);
+       return clk;
+}
index d9d9d9c66dffd2538d0b58cf34021212969836f1..a2432c6960db8f62fe7ab5a72ce89af6cbce4839 100644 (file)
@@ -29,6 +29,9 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
 
+struct clk * imx_obtain_fixed_clock(
+                       const char *name, unsigned long rate);
+
 static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {