Skip to contentSkip to conversation

ARM: i.MX5 Allow DT clock providers

PATCH Superseded Martin Fuzzey 2 participants 2 messages Apr 12, 2013

Subsystems (3)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
 arch/arm/mach-imx/clk-imx51-imx53.c |   75 +++++++++++++++++++----------------
 1 files changed, 41 insertions(+), 34 deletions(-)
arch/arm/mach-imx/clk-imx51-imx53.c +41 -34
index 3228b4e..342c8b3 100644
@@ -117,17 +117,52 @@ enum imx5_clks {
 static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;
 
+
+static struct clk * __init mx5_obtain_fixed_clock_from_dt(const char *name)
+{
+#ifdef CONFIG_OF
+	char compatible[20];
+	struct of_phandle_args phandle = {0};
+	struct clk *clk = NULL;
+
+	scnprintf(compatible, sizeof(compatible), "fsl,imx-%s", name);
+	phandle.np = of_find_compatible_node(NULL, NULL, compatible);
+	if (phandle.np) {
+		clk = of_clk_get_from_provider(&phandle);
+		of_node_put(phandle.np);
+	}
+	return clk;
+#else
+	return NULL;
+#endif
+}
+
+static struct clk * __init mx5_obtain_fixed_clock(
+			const char *name, unsigned long rate)
+{
+	struct clk *clk;
+
+	clk = mx5_obtain_fixed_clock_from_dt(name);
+	if (IS_ERR_OR_NULL(clk))
+		clk = imx_clk_fixed(name, rate);
+	return clk;
+}
+
 static void __init mx5_clocks_common_init(unsigned long rate_ckil,
 		unsigned long rate_osc, unsigned long rate_ckih1,
 		unsigned long rate_ckih2)
 {
 	int i;
 
+#ifdef CONFIG_OF
+	of_clk_init(NULL);
+#endif
+
 	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] = mx5_obtain_fixed_clock("ckil", rate_ckil);
+	clk[osc] = mx5_obtain_fixed_clock("osc", rate_osc);
+	clk[ckih1] = mx5_obtain_fixed_clock("ckih1", rate_ckih1);
+	clk[ckih2] = mx5_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));
@@ -540,41 +575,13 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
 }
 
 #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
maintainer
#1 lore raw

PATCH 1/1 ARM: i.MX5 Allow DT clock providers

Quoted 26 lines · Martin Fuzzey

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.

---
 arch/arm/mach-imx/clk-imx51-imx53.c |   75 +++++++++++++++++++----------------
 1 files changed, 41 insertions(+), 34 deletions(-)
arch/arm/mach-imx/clk-imx51-imx53.c +0 -0
index 3228b4e..342c8b3 100644
@@ -117,17 +117,52 @@ enum imx5_clks {
 static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;

arch/arm/mach-imx/clk-imx51-imx53.c enum imx5_clks { · line 128

Quoted 10 lines
arch/arm/mach-imx/clk-imx51-imx53.c +9 -0
 
+
+static struct clk * __init mx5_obtain_fixed_clock_from_dt(const char *name)
+{
+#ifdef CONFIG_OF
+	char compatible[20];
+	struct of_phandle_args phandle = {0};
+	struct clk *clk = NULL;
+
+	scnprintf(compatible, sizeof(compatible), "fsl,imx-%s", name);

Can we use kasprintf here? Not that it makes a big difference currently, but it always looks a bit awkward to depend on a maximum string length.

Quoted 8 lines
arch/arm/mach-imx/clk-imx51-imx53.c +8 -0
+	phandle.np = of_find_compatible_node(NULL, NULL, compatible);
+	if (phandle.np) {
+		clk = of_clk_get_from_provider(&phandle);
+		of_node_put(phandle.np);
+	}
+	return clk;
+#else
+	return NULL;

arch/arm/mach-imx/clk-imx51-imx53.c enum imx5_clks { · line 146

Quoted 10 lines
arch/arm/mach-imx/clk-imx51-imx53.c +10 -0
+#endif
+}
+
+static struct clk * __init mx5_obtain_fixed_clock(
+			const char *name, unsigned long rate)
+{
+	struct clk *clk;
+
+	clk = mx5_obtain_fixed_clock_from_dt(name);
+	if (IS_ERR_OR_NULL(clk))

You shouldn't use IS_ERR_OR_NULL. Instead you could return ERR_PTR(-ENODEV) for !CONFIG_OF. Another option would be to inline the code from mx5_obtain_fixed_clock_from_dt here.

arch/arm/mach-imx/clk-imx51-imx53.c enum imx5_clks { · line 150

Quoted 4 lines
arch/arm/mach-imx/clk-imx51-imx53.c +4 -0
+		clk = imx_clk_fixed(name, rate);
+	return clk;
+}
+

Sascha

Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |