aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sa1100/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-sa1100/clock.c')
-rw-r--r--arch/arm/mach-sa1100/clock.c91
1 files changed, 66 insertions, 25 deletions
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index dab3c6347a8f..d6df9f6c9f7e 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -11,17 +11,39 @@
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/mutex.h> 13#include <linux/mutex.h>
14#include <linux/io.h>
15#include <linux/clkdev.h>
14 16
15#include <mach/hardware.h> 17#include <mach/hardware.h>
16 18
17/* 19struct clkops {
18 * Very simple clock implementation - we only have one clock to deal with. 20 void (*enable)(struct clk *);
19 */ 21 void (*disable)(struct clk *);
22 unsigned long (*getrate)(struct clk *);
23};
24
20struct clk { 25struct clk {
26 const struct clkops *ops;
27 unsigned long rate;
21 unsigned int enabled; 28 unsigned int enabled;
22}; 29};
23 30
24static void clk_gpio27_enable(void) 31#define INIT_CLKREG(_clk, _devname, _conname) \
32 { \
33 .clk = _clk, \
34 .dev_id = _devname, \
35 .con_id = _conname, \
36 }
37
38#define DEFINE_CLK(_name, _ops, _rate) \
39struct clk clk_##_name = { \
40 .ops = _ops, \
41 .rate = _rate, \
42 }
43
44static DEFINE_SPINLOCK(clocks_lock);
45
46static void clk_gpio27_enable(struct clk *clk)
25{ 47{
26 /* 48 /*
27 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: 49 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -32,38 +54,22 @@ static void clk_gpio27_enable(void)
32 TUCR = TUCR_3_6864MHz; 54 TUCR = TUCR_3_6864MHz;
33} 55}
34 56
35static void clk_gpio27_disable(void) 57static void clk_gpio27_disable(struct clk *clk)
36{ 58{
37 TUCR = 0; 59 TUCR = 0;
38 GPDR &= ~GPIO_32_768kHz; 60 GPDR &= ~GPIO_32_768kHz;
39 GAFR &= ~GPIO_32_768kHz; 61 GAFR &= ~GPIO_32_768kHz;
40} 62}
41 63
42static struct clk clk_gpio27;
43
44static DEFINE_SPINLOCK(clocks_lock);
45
46struct clk *clk_get(struct device *dev, const char *id)
47{
48 const char *devname = dev_name(dev);
49
50 return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
51}
52EXPORT_SYMBOL(clk_get);
53
54void clk_put(struct clk *clk)
55{
56}
57EXPORT_SYMBOL(clk_put);
58
59int clk_enable(struct clk *clk) 64int clk_enable(struct clk *clk)
60{ 65{
61 unsigned long flags; 66 unsigned long flags;
62 67
63 spin_lock_irqsave(&clocks_lock, flags); 68 spin_lock_irqsave(&clocks_lock, flags);
64 if (clk->enabled++ == 0) 69 if (clk->enabled++ == 0)
65 clk_gpio27_enable(); 70 clk->ops->enable(clk);
66 spin_unlock_irqrestore(&clocks_lock, flags); 71 spin_unlock_irqrestore(&clocks_lock, flags);
72
67 return 0; 73 return 0;
68} 74}
69EXPORT_SYMBOL(clk_enable); 75EXPORT_SYMBOL(clk_enable);
@@ -76,13 +82,48 @@ void clk_disable(struct clk *clk)
76 82
77 spin_lock_irqsave(&clocks_lock, flags); 83 spin_lock_irqsave(&clocks_lock, flags);
78 if (--clk->enabled == 0) 84 if (--clk->enabled == 0)
79 clk_gpio27_disable(); 85 clk->ops->disable(clk);
80 spin_unlock_irqrestore(&clocks_lock, flags); 86 spin_unlock_irqrestore(&clocks_lock, flags);
81} 87}
82EXPORT_SYMBOL(clk_disable); 88EXPORT_SYMBOL(clk_disable);
83 89
84unsigned long clk_get_rate(struct clk *clk) 90unsigned long clk_get_rate(struct clk *clk)
85{ 91{
86 return 3686400; 92 unsigned long rate;
93
94 rate = clk->rate;
95 if (clk->ops->getrate)
96 rate = clk->ops->getrate(clk);
97
98 return rate;
87} 99}
88EXPORT_SYMBOL(clk_get_rate); 100EXPORT_SYMBOL(clk_get_rate);
101
102const struct clkops clk_gpio27_ops = {
103 .enable = clk_gpio27_enable,
104 .disable = clk_gpio27_disable,
105};
106
107static void clk_dummy_enable(struct clk *clk) { }
108static void clk_dummy_disable(struct clk *clk) { }
109
110const struct clkops clk_dummy_ops = {
111 .enable = clk_dummy_enable,
112 .disable = clk_dummy_disable,
113};
114
115static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400);
116static DEFINE_CLK(dummy, &clk_dummy_ops, 0);
117
118static struct clk_lookup sa11xx_clkregs[] = {
119 INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL),
120 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
121};
122
123static int __init sa11xx_clk_init(void)
124{
125 clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
126 return 0;
127}
128
129postcore_initcall(sa11xx_clk_init);