1 /***************************************************************************/
4 * clk.c -- general ColdFire CPU kernel clk handling
6 * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
9 /***************************************************************************/
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/mutex.h>
15 #include <linux/clk.h>
17 #include <linux/err.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
20 #include <asm/mcfclk.h>
22 static DEFINE_SPINLOCK(clk_lock
);
26 * For more advanced ColdFire parts that have clocks that can be enabled
27 * we supply enable/disable functions. These must properly define their
28 * clocks in their platform specific code.
30 void __clk_init_enabled(struct clk
*clk
)
33 clk
->clk_ops
->enable(clk
);
36 void __clk_init_disabled(struct clk
*clk
)
39 clk
->clk_ops
->disable(clk
);
42 static void __clk_enable0(struct clk
*clk
)
44 __raw_writeb(clk
->slot
, MCFPM_PPMCR0
);
47 static void __clk_disable0(struct clk
*clk
)
49 __raw_writeb(clk
->slot
, MCFPM_PPMSR0
);
52 struct clk_ops clk_ops0
= {
53 .enable
= __clk_enable0
,
54 .disable
= __clk_disable0
,
58 static void __clk_enable1(struct clk
*clk
)
60 __raw_writeb(clk
->slot
, MCFPM_PPMCR1
);
63 static void __clk_disable1(struct clk
*clk
)
65 __raw_writeb(clk
->slot
, MCFPM_PPMSR1
);
68 struct clk_ops clk_ops1
= {
69 .enable
= __clk_enable1
,
70 .disable
= __clk_disable1
,
72 #endif /* MCFPM_PPMCR1 */
73 #endif /* MCFPM_PPMCR0 */
75 struct clk
*clk_get(struct device
*dev
, const char *id
)
77 const char *clk_name
= dev
? dev_name(dev
) : id
? id
: NULL
;
81 for (i
= 0; (clk
= mcf_clks
[i
]) != NULL
; ++i
)
82 if (!strcmp(clk
->name
, clk_name
))
84 pr_warn("clk_get: didn't find clock %s\n", clk_name
);
85 return ERR_PTR(-ENOENT
);
87 EXPORT_SYMBOL(clk_get
);
89 int clk_enable(struct clk
*clk
)
92 spin_lock_irqsave(&clk_lock
, flags
);
93 if ((clk
->enabled
++ == 0) && clk
->clk_ops
)
94 clk
->clk_ops
->enable(clk
);
95 spin_unlock_irqrestore(&clk_lock
, flags
);
99 EXPORT_SYMBOL(clk_enable
);
101 void clk_disable(struct clk
*clk
)
104 spin_lock_irqsave(&clk_lock
, flags
);
105 if ((--clk
->enabled
== 0) && clk
->clk_ops
)
106 clk
->clk_ops
->disable(clk
);
107 spin_unlock_irqrestore(&clk_lock
, flags
);
109 EXPORT_SYMBOL(clk_disable
);
111 void clk_put(struct clk
*clk
)
113 if (clk
->enabled
!= 0)
114 pr_warn("clk_put %s still enabled\n", clk
->name
);
116 EXPORT_SYMBOL(clk_put
);
118 unsigned long clk_get_rate(struct clk
*clk
)
122 EXPORT_SYMBOL(clk_get_rate
);
124 /***************************************************************************/