Skip to content

Commit

Permalink
ARM: i.MX5: Allow DT clock providers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Martin Fuzzey authored and Shawn Guo committed Jun 17, 2013
1 parent 7d13205 commit 75f83d0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 36 deletions.
44 changes: 8 additions & 36 deletions arch/arm/mach-imx/clk-imx51-imx53.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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
35 changes: 35 additions & 0 deletions arch/arm/mach-imx/clk.c
Original file line number Diff line number Diff line change
@@ -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;
}
3 changes: 3 additions & 0 deletions arch/arm/mach-imx/clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit 75f83d0

Please sign in to comment.