xref: /openbmc/linux/arch/arm/mach-sa1100/clock.c (revision 384740dc)
1 /*
2  *  linux/arch/arm/mach-sa1100/clock.c
3  */
4 #include <linux/module.h>
5 #include <linux/kernel.h>
6 #include <linux/list.h>
7 #include <linux/errno.h>
8 #include <linux/err.h>
9 #include <linux/string.h>
10 #include <linux/clk.h>
11 #include <linux/spinlock.h>
12 #include <linux/mutex.h>
13 
14 #include <mach/hardware.h>
15 
16 /*
17  * Very simple clock implementation - we only have one clock to
18  * deal with at the moment, so we only match using the "name".
19  */
20 struct clk {
21 	struct list_head	node;
22 	unsigned long		rate;
23 	const char		*name;
24 	unsigned int		enabled;
25 	void			(*enable)(void);
26 	void			(*disable)(void);
27 };
28 
29 static LIST_HEAD(clocks);
30 static DEFINE_MUTEX(clocks_mutex);
31 static DEFINE_SPINLOCK(clocks_lock);
32 
33 struct clk *clk_get(struct device *dev, const char *id)
34 {
35 	struct clk *p, *clk = ERR_PTR(-ENOENT);
36 
37 	mutex_lock(&clocks_mutex);
38 	list_for_each_entry(p, &clocks, node) {
39 		if (strcmp(id, p->name) == 0) {
40 			clk = p;
41 			break;
42 		}
43 	}
44 	mutex_unlock(&clocks_mutex);
45 
46 	return clk;
47 }
48 EXPORT_SYMBOL(clk_get);
49 
50 void clk_put(struct clk *clk)
51 {
52 }
53 EXPORT_SYMBOL(clk_put);
54 
55 int clk_enable(struct clk *clk)
56 {
57 	unsigned long flags;
58 
59 	spin_lock_irqsave(&clocks_lock, flags);
60 	if (clk->enabled++ == 0)
61 		clk->enable();
62 	spin_unlock_irqrestore(&clocks_lock, flags);
63 	return 0;
64 }
65 EXPORT_SYMBOL(clk_enable);
66 
67 void clk_disable(struct clk *clk)
68 {
69 	unsigned long flags;
70 
71 	WARN_ON(clk->enabled == 0);
72 
73 	spin_lock_irqsave(&clocks_lock, flags);
74 	if (--clk->enabled == 0)
75 		clk->disable();
76 	spin_unlock_irqrestore(&clocks_lock, flags);
77 }
78 EXPORT_SYMBOL(clk_disable);
79 
80 unsigned long clk_get_rate(struct clk *clk)
81 {
82 	return clk->rate;
83 }
84 EXPORT_SYMBOL(clk_get_rate);
85 
86 
87 static void clk_gpio27_enable(void)
88 {
89 	/*
90 	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
91 	 * (SA-1110 Developer's Manual, section 9.1.2.1)
92 	 */
93 	GAFR |= GPIO_32_768kHz;
94 	GPDR |= GPIO_32_768kHz;
95 	TUCR = TUCR_3_6864MHz;
96 }
97 
98 static void clk_gpio27_disable(void)
99 {
100 	TUCR = 0;
101 	GPDR &= ~GPIO_32_768kHz;
102 	GAFR &= ~GPIO_32_768kHz;
103 }
104 
105 static struct clk clk_gpio27 = {
106 	.name		= "SA1111_CLK",
107 	.rate		= 3686400,
108 	.enable		= clk_gpio27_enable,
109 	.disable	= clk_gpio27_disable,
110 };
111 
112 int clk_register(struct clk *clk)
113 {
114 	mutex_lock(&clocks_mutex);
115 	list_add(&clk->node, &clocks);
116 	mutex_unlock(&clocks_mutex);
117 	return 0;
118 }
119 EXPORT_SYMBOL(clk_register);
120 
121 void clk_unregister(struct clk *clk)
122 {
123 	mutex_lock(&clocks_mutex);
124 	list_del(&clk->node);
125 	mutex_unlock(&clocks_mutex);
126 }
127 EXPORT_SYMBOL(clk_unregister);
128 
129 static int __init clk_init(void)
130 {
131 	clk_register(&clk_gpio27);
132 	return 0;
133 }
134 arch_initcall(clk_init);
135