aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorJett.Zhou <jtzhou@marvell.com>2011-11-30 01:32:36 -0500
committerArnd Bergmann <arnd@arndb.de>2011-12-28 05:42:48 -0500
commitedf3ff5bac2582b57de4e7c6569fee5d7c1c0a42 (patch)
treef41ccef3e8d8a35f53dbbc8e5878ee1630493e45 /arch/arm
parent7557c175f60d8d40baf16b22caf79beadef8f081 (diff)
ARM: sa1100: clean up of the clock support
Signed-off-by: Jett.Zhou <jtzhou@marvell.com> Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-sa1100/clock.c91
2 files changed, 67 insertions, 26 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e084b7e981e8..86ebbc5ffcd1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -738,7 +738,7 @@ config ARCH_SA1100
738 select ARCH_HAS_CPUFREQ 738 select ARCH_HAS_CPUFREQ
739 select CPU_FREQ 739 select CPU_FREQ
740 select GENERIC_CLOCKEVENTS 740 select GENERIC_CLOCKEVENTS
741 select HAVE_CLK 741 select CLKDEV_LOOKUP
742 select HAVE_SCHED_CLOCK 742 select HAVE_SCHED_CLOCK
743 select TICK_ONESHOT 743 select TICK_ONESHOT
744 select ARCH_REQUIRE_GPIOLIB 744 select ARCH_REQUIRE_GPIOLIB
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);