aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorMartin Fuzzey <mfuzzey@parkeon.com>2013-04-23 08:16:59 -0400
committerShawn Guo <shawn.guo@linaro.org>2013-06-17 03:45:09 -0400
commit75f83d06c3305e0f0a00e7d141acf8ceef608fe9 (patch)
tree6f71c11c803414b0075af8a5b642212cfff7136d /arch/arm
parent7d132055814ef17a6c7b69f342244c410a5e000f (diff)
ARM: i.MX5: Allow DT clock providers
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>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c44
-rw-r--r--arch/arm/mach-imx/clk.c35
-rw-r--r--arch/arm/mach-imx/clk.h3
3 files changed, 46 insertions, 36 deletions
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 6fc486b6a3c6..929762742ee1 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -123,11 +123,13 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
123{ 123{
124 int i; 124 int i;
125 125
126 of_clk_init(NULL);
127
126 clk[dummy] = imx_clk_fixed("dummy", 0); 128 clk[dummy] = imx_clk_fixed("dummy", 0);
127 clk[ckil] = imx_clk_fixed("ckil", rate_ckil); 129 clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
128 clk[osc] = imx_clk_fixed("osc", rate_osc); 130 clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
129 clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1); 131 clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1);
130 clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2); 132 clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2);
131 133
132 clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, 134 clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
133 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 135 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,
542 return 0; 544 return 0;
543} 545}
544 546
545#ifdef CONFIG_OF
546static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
547 unsigned long *ckih1, unsigned long *ckih2)
548{
549 struct device_node *np;
550
551 /* retrieve the freqency of fixed clocks from device tree */
552 for_each_compatible_node(np, NULL, "fixed-clock") {
553 u32 rate;
554 if (of_property_read_u32(np, "clock-frequency", &rate))
555 continue;
556
557 if (of_device_is_compatible(np, "fsl,imx-ckil"))
558 *ckil = rate;
559 else if (of_device_is_compatible(np, "fsl,imx-osc"))
560 *osc = rate;
561 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
562 *ckih1 = rate;
563 else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
564 *ckih2 = rate;
565 }
566}
567
568int __init mx51_clocks_init_dt(void) 547int __init mx51_clocks_init_dt(void)
569{ 548{
570 unsigned long ckil, osc, ckih1, ckih2; 549 return mx51_clocks_init(0, 0, 0, 0);
571
572 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
573 return mx51_clocks_init(ckil, osc, ckih1, ckih2);
574} 550}
575 551
576int __init mx53_clocks_init_dt(void) 552int __init mx53_clocks_init_dt(void)
577{ 553{
578 unsigned long ckil, osc, ckih1, ckih2; 554 return mx53_clocks_init(0, 0, 0, 0);
579
580 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
581 return mx53_clocks_init(ckil, osc, ckih1, ckih2);
582} 555}
583#endif
diff --git a/arch/arm/mach-imx/clk.c b/arch/arm/mach-imx/clk.c
index 37e884ed1cd4..53e8788b0d0f 100644
--- a/arch/arm/mach-imx/clk.c
+++ b/arch/arm/mach-imx/clk.c
@@ -1,4 +1,39 @@
1#include <linux/clk.h>
2#include <linux/err.h>
3#include <linux/of.h>
4#include <linux/slab.h>
1#include <linux/spinlock.h> 5#include <linux/spinlock.h>
2#include "clk.h" 6#include "clk.h"
3 7
4DEFINE_SPINLOCK(imx_ccm_lock); 8DEFINE_SPINLOCK(imx_ccm_lock);
9
10static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
11{
12 struct of_phandle_args phandle = {0};
13 struct clk *clk = ERR_PTR(-ENODEV);
14 char *path;
15
16 path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
17 if (!path)
18 return ERR_PTR(-ENOMEM);
19
20 phandle.np = of_find_node_by_path(path);
21 kfree(path);
22
23 if (phandle.np) {
24 clk = of_clk_get_from_provider(&phandle);
25 of_node_put(phandle.np);
26 }
27 return clk;
28}
29
30struct clk * __init imx_obtain_fixed_clock(
31 const char *name, unsigned long rate)
32{
33 struct clk *clk;
34
35 clk = imx_obtain_fixed_clock_from_dt(name);
36 if (IS_ERR(clk))
37 clk = imx_clk_fixed(name, rate);
38 return clk;
39}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index d9d9d9c66dff..a2432c6960db 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -29,6 +29,9 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
29 void __iomem *reg, u8 bit_idx, 29 void __iomem *reg, u8 bit_idx,
30 u8 clk_gate_flags, spinlock_t *lock); 30 u8 clk_gate_flags, spinlock_t *lock);
31 31
32struct clk * imx_obtain_fixed_clock(
33 const char *name, unsigned long rate);
34
32static inline struct clk *imx_clk_gate2(const char *name, const char *parent, 35static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
33 void __iomem *reg, u8 shift) 36 void __iomem *reg, u8 shift)
34{ 37{