aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/common/Kconfig3
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/clkdev.c128
-rw-r--r--arch/arm/include/asm/clkdev.h30
-rw-r--r--arch/arm/mach-integrator/clock.c80
-rw-r--r--arch/arm/mach-integrator/clock.h25
-rw-r--r--arch/arm/mach-integrator/core.c35
-rw-r--r--arch/arm/mach-integrator/impd1.c26
-rw-r--r--arch/arm/mach-integrator/include/mach/clkdev.h25
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c18
-rw-r--r--arch/arm/mach-pxa/clock.c66
-rw-r--r--arch/arm/mach-pxa/clock.h59
-rw-r--r--arch/arm/mach-pxa/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-pxa/pwm.c2
-rw-r--r--arch/arm/mach-pxa/pxa25x.c71
-rw-r--r--arch/arm/mach-pxa/pxa27x.c89
-rw-r--r--arch/arm/mach-pxa/pxa300.c18
-rw-r--r--arch/arm/mach-pxa/pxa320.c8
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c87
-rw-r--r--arch/arm/mach-pxa/ssp.c2
-rw-r--r--arch/arm/mach-realview/clock.c80
-rw-r--r--arch/arm/mach-realview/clock.h6
-rw-r--r--arch/arm/mach-realview/core.c52
-rw-r--r--arch/arm/mach-realview/core.h1
-rw-r--r--arch/arm/mach-realview/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-sa1100/clock.c100
-rw-r--r--arch/arm/mach-versatile/clock.c80
-rw-r--r--arch/arm/mach-versatile/clock.h7
-rw-r--r--arch/arm/mach-versatile/core.c56
-rw-r--r--arch/arm/mach-versatile/include/mach/clkdev.h7
34 files changed, 608 insertions, 578 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 60a09fcc4af8..a04199771730 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -211,6 +211,7 @@ config ARCH_INTEGRATOR
211 bool "ARM Ltd. Integrator family" 211 bool "ARM Ltd. Integrator family"
212 select ARM_AMBA 212 select ARM_AMBA
213 select HAVE_CLK 213 select HAVE_CLK
214 select COMMON_CLKDEV
214 select ICST525 215 select ICST525
215 help 216 help
216 Support for ARM's Integrator platform. 217 Support for ARM's Integrator platform.
@@ -219,6 +220,7 @@ config ARCH_REALVIEW
219 bool "ARM Ltd. RealView family" 220 bool "ARM Ltd. RealView family"
220 select ARM_AMBA 221 select ARM_AMBA
221 select HAVE_CLK 222 select HAVE_CLK
223 select COMMON_CLKDEV
222 select ICST307 224 select ICST307
223 select GENERIC_TIME 225 select GENERIC_TIME
224 select GENERIC_CLOCKEVENTS 226 select GENERIC_CLOCKEVENTS
@@ -230,6 +232,7 @@ config ARCH_VERSATILE
230 select ARM_AMBA 232 select ARM_AMBA
231 select ARM_VIC 233 select ARM_VIC
232 select HAVE_CLK 234 select HAVE_CLK
235 select COMMON_CLKDEV
233 select ICST307 236 select ICST307
234 select GENERIC_TIME 237 select GENERIC_TIME
235 select GENERIC_CLOCKEVENTS 238 select GENERIC_CLOCKEVENTS
@@ -477,6 +480,7 @@ config ARCH_PXA
477 select ARCH_MTD_XIP 480 select ARCH_MTD_XIP
478 select GENERIC_GPIO 481 select GENERIC_GPIO
479 select HAVE_CLK 482 select HAVE_CLK
483 select COMMON_CLKDEV
480 select ARCH_REQUIRE_GPIOLIB 484 select ARCH_REQUIRE_GPIOLIB
481 select GENERIC_TIME 485 select GENERIC_TIME
482 select GENERIC_CLOCKEVENTS 486 select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 86b5e6982660..a2cd9beaf37d 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -33,3 +33,6 @@ config SHARPSL_PM
33 33
34config SHARP_SCOOP 34config SHARP_SCOOP
35 bool 35 bool
36
37config COMMON_CLKDEV
38 bool
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 325e4b6a6afb..7cb7961d81cb 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SHARP_SCOOP) += scoop.o
17obj-$(CONFIG_ARCH_IXP2000) += uengine.o 17obj-$(CONFIG_ARCH_IXP2000) += uengine.o
18obj-$(CONFIG_ARCH_IXP23XX) += uengine.o 18obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
19obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o 19obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
20obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
new file mode 100644
index 000000000000..17a17b49a45b
--- /dev/null
+++ b/arch/arm/common/clkdev.c
@@ -0,0 +1,128 @@
1/*
2 * arch/arm/common/clkdev.c
3 *
4 * Copyright (C) 2008 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Helper for the clk API to assist looking up a struct clk.
11 */
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/device.h>
15#include <linux/list.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18#include <linux/string.h>
19#include <linux/mutex.h>
20
21#include <asm/clkdev.h>
22#include <mach/clkdev.h>
23
24static LIST_HEAD(clocks);
25static DEFINE_MUTEX(clocks_mutex);
26
27static struct clk *clk_find(const char *dev_id, const char *con_id)
28{
29 struct clk_lookup *p;
30 struct clk *clk = NULL;
31 int match, best = 0;
32
33 list_for_each_entry(p, &clocks, node) {
34 if ((p->dev_id && !dev_id) || (p->con_id && !con_id))
35 continue;
36 match = 0;
37 if (p->dev_id)
38 match += 2 * (strcmp(p->dev_id, dev_id) == 0);
39 if (p->con_id)
40 match += 1 * (strcmp(p->con_id, con_id) == 0);
41 if (match == 0)
42 continue;
43
44 if (match > best) {
45 clk = p->clk;
46 best = match;
47 }
48 }
49 return clk;
50}
51
52struct clk *clk_get(struct device *dev, const char *con_id)
53{
54 const char *dev_id = dev ? dev_name(dev) : NULL;
55 struct clk *clk;
56
57 mutex_lock(&clocks_mutex);
58 clk = clk_find(dev_id, con_id);
59 if (clk && !__clk_get(clk))
60 clk = NULL;
61 mutex_unlock(&clocks_mutex);
62
63 return clk ? clk : ERR_PTR(-ENOENT);
64}
65EXPORT_SYMBOL(clk_get);
66
67void clk_put(struct clk *clk)
68{
69 __clk_put(clk);
70}
71EXPORT_SYMBOL(clk_put);
72
73void clkdev_add(struct clk_lookup *cl)
74{
75 mutex_lock(&clocks_mutex);
76 list_add_tail(&cl->node, &clocks);
77 mutex_unlock(&clocks_mutex);
78}
79EXPORT_SYMBOL(clkdev_add);
80
81#define MAX_DEV_ID 20
82#define MAX_CON_ID 16
83
84struct clk_lookup_alloc {
85 struct clk_lookup cl;
86 char dev_id[MAX_DEV_ID];
87 char con_id[MAX_CON_ID];
88};
89
90struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
91 const char *dev_fmt, ...)
92{
93 struct clk_lookup_alloc *cla;
94
95 cla = kzalloc(sizeof(*cla), GFP_KERNEL);
96 if (!cla)
97 return NULL;
98
99 cla->cl.clk = clk;
100 if (con_id) {
101 strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
102 cla->cl.con_id = cla->con_id;
103 }
104
105 if (dev_fmt) {
106 va_list ap;
107
108 va_start(ap, dev_fmt);
109 vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
110 cla->cl.dev_id = cla->dev_id;
111 va_end(ap);
112 }
113
114 return &cla->cl;
115}
116EXPORT_SYMBOL(clkdev_alloc);
117
118/*
119 * clkdev_drop - remove a clock dynamically allocated
120 */
121void clkdev_drop(struct clk_lookup *cl)
122{
123 mutex_lock(&clocks_mutex);
124 list_del(&cl->node);
125 mutex_unlock(&clocks_mutex);
126 kfree(cl);
127}
128EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
new file mode 100644
index 000000000000..b6ec7c627b39
--- /dev/null
+++ b/arch/arm/include/asm/clkdev.h
@@ -0,0 +1,30 @@
1/*
2 * arch/arm/include/asm/clkdev.h
3 *
4 * Copyright (C) 2008 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Helper for the clk API to assist looking up a struct clk.
11 */
12#ifndef __ASM_CLKDEV_H
13#define __ASM_CLKDEV_H
14
15struct clk;
16
17struct clk_lookup {
18 struct list_head node;
19 const char *dev_id;
20 const char *con_id;
21 struct clk *clk;
22};
23
24struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
25 const char *dev_fmt, ...);
26
27void clkdev_add(struct clk_lookup *cl);
28void clkdev_drop(struct clk_lookup *cl);
29
30#endif
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
index 8d761fdd2ecd..989ecf5f5c46 100644
--- a/arch/arm/mach-integrator/clock.c
+++ b/arch/arm/mach-integrator/clock.c
@@ -10,42 +10,12 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
15#include <linux/err.h>
16#include <linux/string.h>
17#include <linux/clk.h> 14#include <linux/clk.h>
18#include <linux/mutex.h> 15#include <linux/mutex.h>
19 16
20#include <asm/hardware/icst525.h> 17#include <asm/clkdev.h>
21 18#include <mach/clkdev.h>
22#include "clock.h"
23
24static LIST_HEAD(clocks);
25static DEFINE_MUTEX(clocks_mutex);
26
27struct clk *clk_get(struct device *dev, const char *id)
28{
29 struct clk *p, *clk = ERR_PTR(-ENOENT);
30
31 mutex_lock(&clocks_mutex);
32 list_for_each_entry(p, &clocks, node) {
33 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
34 clk = p;
35 break;
36 }
37 }
38 mutex_unlock(&clocks_mutex);
39
40 return clk;
41}
42EXPORT_SYMBOL(clk_get);
43
44void clk_put(struct clk *clk)
45{
46 module_put(clk->owner);
47}
48EXPORT_SYMBOL(clk_put);
49 19
50int clk_enable(struct clk *clk) 20int clk_enable(struct clk *clk)
51{ 21{
@@ -67,7 +37,6 @@ EXPORT_SYMBOL(clk_get_rate);
67long clk_round_rate(struct clk *clk, unsigned long rate) 37long clk_round_rate(struct clk *clk, unsigned long rate)
68{ 38{
69 struct icst525_vco vco; 39 struct icst525_vco vco;
70
71 vco = icst525_khz_to_vco(clk->params, rate / 1000); 40 vco = icst525_khz_to_vco(clk->params, rate / 1000);
72 return icst525_khz(clk->params, vco) * 1000; 41 return icst525_khz(clk->params, vco) * 1000;
73} 42}
@@ -76,56 +45,15 @@ EXPORT_SYMBOL(clk_round_rate);
76int clk_set_rate(struct clk *clk, unsigned long rate) 45int clk_set_rate(struct clk *clk, unsigned long rate)
77{ 46{
78 int ret = -EIO; 47 int ret = -EIO;
48
79 if (clk->setvco) { 49 if (clk->setvco) {
80 struct icst525_vco vco; 50 struct icst525_vco vco;
81 51
82 vco = icst525_khz_to_vco(clk->params, rate / 1000); 52 vco = icst525_khz_to_vco(clk->params, rate / 1000);
83 clk->rate = icst525_khz(clk->params, vco) * 1000; 53 clk->rate = icst525_khz(clk->params, vco) * 1000;
84
85 printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
86 clk->name, vco.s, vco.r, vco.v);
87
88 clk->setvco(clk, vco); 54 clk->setvco(clk, vco);
89 ret = 0; 55 ret = 0;
90 } 56 }
91 return 0; 57 return ret;
92} 58}
93EXPORT_SYMBOL(clk_set_rate); 59EXPORT_SYMBOL(clk_set_rate);
94
95/*
96 * These are fixed clocks.
97 */
98static struct clk kmi_clk = {
99 .name = "KMIREFCLK",
100 .rate = 24000000,
101};
102
103static struct clk uart_clk = {
104 .name = "UARTCLK",
105 .rate = 14745600,
106};
107
108int clk_register(struct clk *clk)
109{
110 mutex_lock(&clocks_mutex);
111 list_add(&clk->node, &clocks);
112 mutex_unlock(&clocks_mutex);
113 return 0;
114}
115EXPORT_SYMBOL(clk_register);
116
117void clk_unregister(struct clk *clk)
118{
119 mutex_lock(&clocks_mutex);
120 list_del(&clk->node);
121 mutex_unlock(&clocks_mutex);
122}
123EXPORT_SYMBOL(clk_unregister);
124
125static int __init clk_init(void)
126{
127 clk_register(&kmi_clk);
128 clk_register(&uart_clk);
129 return 0;
130}
131arch_initcall(clk_init);
diff --git a/arch/arm/mach-integrator/clock.h b/arch/arm/mach-integrator/clock.h
index 09e6328ceba9..e69de29bb2d1 100644
--- a/arch/arm/mach-integrator/clock.h
+++ b/arch/arm/mach-integrator/clock.h
@@ -1,25 +0,0 @@
1/*
2 * linux/arch/arm/mach-integrator/clock.h
3 *
4 * Copyright (C) 2004 ARM Limited.
5 * Written by Deep Blue Solutions Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11struct module;
12struct icst525_params;
13
14struct clk {
15 struct list_head node;
16 unsigned long rate;
17 struct module *owner;
18 const char *name;
19 const struct icst525_params *params;
20 void *data;
21 void (*setvco)(struct clk *, struct icst525_vco vco);
22};
23
24int clk_register(struct clk *clk);
25void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 595b7392ee4e..c89c949b4d45 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -21,6 +21,8 @@
21#include <linux/amba/serial.h> 21#include <linux/amba/serial.h>
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/clkdev.h>
25#include <mach/clkdev.h>
24#include <mach/hardware.h> 26#include <mach/hardware.h>
25#include <asm/irq.h> 27#include <asm/irq.h>
26#include <asm/hardware/arm_timer.h> 28#include <asm/hardware/arm_timer.h>
@@ -108,10 +110,43 @@ static struct amba_device *amba_devs[] __initdata = {
108 &kmi1_device, 110 &kmi1_device,
109}; 111};
110 112
113/*
114 * These are fixed clocks.
115 */
116static struct clk clk24mhz = {
117 .rate = 24000000,
118};
119
120static struct clk uartclk = {
121 .rate = 14745600,
122};
123
124static struct clk_lookup lookups[] __initdata = {
125 { /* UART0 */
126 .dev_id = "mb:16",
127 .clk = &uartclk,
128 }, { /* UART1 */
129 .dev_id = "mb:17",
130 .clk = &uartclk,
131 }, { /* KMI0 */
132 .dev_id = "mb:18",
133 .clk = &clk24mhz,
134 }, { /* KMI1 */
135 .dev_id = "mb:19",
136 .clk = &clk24mhz,
137 }, { /* MMCI - IntegratorCP */
138 .dev_id = "mb:1c",
139 .clk = &uartclk,
140 }
141};
142
111static int __init integrator_init(void) 143static int __init integrator_init(void)
112{ 144{
113 int i; 145 int i;
114 146
147 for (i = 0; i < ARRAY_SIZE(lookups); i++)
148 clkdev_add(&lookups[i]);
149
115 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 150 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
116 struct amba_device *d = amba_devs[i]; 151 struct amba_device *d = amba_devs[i];
117 amba_device_register(d, &iomem_resource); 152 amba_device_register(d, &iomem_resource);
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 172299a78302..0058c937719e 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -22,13 +22,13 @@
22#include <linux/amba/clcd.h> 22#include <linux/amba/clcd.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24
25#include <asm/clkdev.h>
26#include <mach/clkdev.h>
25#include <asm/hardware/icst525.h> 27#include <asm/hardware/icst525.h>
26#include <mach/lm.h> 28#include <mach/lm.h>
27#include <mach/impd1.h> 29#include <mach/impd1.h>
28#include <asm/sizes.h> 30#include <asm/sizes.h>
29 31
30#include "clock.h"
31
32static int module_id; 32static int module_id;
33 33
34module_param_named(lmid, module_id, int, 0444); 34module_param_named(lmid, module_id, int, 0444);
@@ -37,6 +37,7 @@ MODULE_PARM_DESC(lmid, "logic module stack position");
37struct impd1_module { 37struct impd1_module {
38 void __iomem *base; 38 void __iomem *base;
39 struct clk vcos[2]; 39 struct clk vcos[2];
40 struct clk_lookup *clks[3];
40}; 41};
41 42
42static const struct icst525_params impd1_vco_params = { 43static const struct icst525_params impd1_vco_params = {
@@ -339,9 +340,8 @@ static struct impd1_device impd1_devs[] = {
339 } 340 }
340}; 341};
341 342
342static const char *impd1_vconames[2] = { 343static struct clk fixed_14745600 = {
343 "CLCDCLK", 344 .rate = 14745600,
344 "AUXVCO2",
345}; 345};
346 346
347static int impd1_probe(struct lm_device *dev) 347static int impd1_probe(struct lm_device *dev)
@@ -374,14 +374,20 @@ static int impd1_probe(struct lm_device *dev)
374 374
375 for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { 375 for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
376 impd1->vcos[i].owner = THIS_MODULE, 376 impd1->vcos[i].owner = THIS_MODULE,
377 impd1->vcos[i].name = impd1_vconames[i],
378 impd1->vcos[i].params = &impd1_vco_params, 377 impd1->vcos[i].params = &impd1_vco_params,
379 impd1->vcos[i].data = impd1, 378 impd1->vcos[i].data = impd1,
380 impd1->vcos[i].setvco = impd1_setvco; 379 impd1->vcos[i].setvco = impd1_setvco;
381
382 clk_register(&impd1->vcos[i]);
383 } 380 }
384 381
382 impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
383 dev->id);
384 impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100",
385 dev->id);
386 impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200",
387 dev->id);
388 for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
389 clkdev_add(impd1->clks[i]);
390
385 for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { 391 for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
386 struct impd1_device *idev = impd1_devs + i; 392 struct impd1_device *idev = impd1_devs + i;
387 struct amba_device *d; 393 struct amba_device *d;
@@ -434,8 +440,8 @@ static void impd1_remove(struct lm_device *dev)
434 440
435 device_for_each_child(&dev->dev, NULL, impd1_remove_one); 441 device_for_each_child(&dev->dev, NULL, impd1_remove_one);
436 442
437 for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) 443 for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
438 clk_unregister(&impd1->vcos[i]); 444 clkdev_drop(impd1->clks[i]);
439 445
440 lm_set_drvdata(dev, NULL); 446 lm_set_drvdata(dev, NULL);
441 447
diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h
new file mode 100644
index 000000000000..9293e410832a
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/clkdev.h
@@ -0,0 +1,25 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#include <linux/module.h>
5#include <asm/hardware/icst525.h>
6
7struct clk {
8 unsigned long rate;
9 struct module *owner;
10 const struct icst525_params *params;
11 void *data;
12 void (*setvco)(struct clk *, struct icst525_vco vco);
13};
14
15static inline int __clk_get(struct clk *clk)
16{
17 return try_module_get(clk->owner);
18}
19
20static inline void __clk_put(struct clk *clk)
21{
22 module_put(clk->owner);
23}
24
25#endif
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 88026ccd5ac9..427c2d8dc123 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -21,6 +21,8 @@
21#include <linux/amba/clcd.h> 21#include <linux/amba/clcd.h>
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/clkdev.h>
25#include <mach/clkdev.h>
24#include <mach/hardware.h> 26#include <mach/hardware.h>
25#include <asm/irq.h> 27#include <asm/irq.h>
26#include <asm/setup.h> 28#include <asm/setup.h>
@@ -38,7 +40,6 @@
38#include <asm/mach/time.h> 40#include <asm/mach/time.h>
39 41
40#include "common.h" 42#include "common.h"
41#include "clock.h"
42 43
43#define INTCP_PA_MMC_BASE 0x1c000000 44#define INTCP_PA_MMC_BASE 0x1c000000
44#define INTCP_PA_AACI_BASE 0x1d000000 45#define INTCP_PA_AACI_BASE 0x1d000000
@@ -289,15 +290,16 @@ static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
289 writel(0, CM_LOCK); 290 writel(0, CM_LOCK);
290} 291}
291 292
292static struct clk cp_clcd_clk = { 293static struct clk cp_auxclk = {
293 .name = "CLCDCLK",
294 .params = &cp_auxvco_params, 294 .params = &cp_auxvco_params,
295 .setvco = cp_auxvco_set, 295 .setvco = cp_auxvco_set,
296}; 296};
297 297
298static struct clk cp_mmci_clk = { 298static struct clk_lookup cp_lookups[] = {
299 .name = "MCLK", 299 { /* CLCD */
300 .rate = 14745600, 300 .dev_id = "mb:c0",
301 .clk = &cp_auxclk,
302 },
301}; 303};
302 304
303/* 305/*
@@ -554,8 +556,8 @@ static void __init intcp_init(void)
554{ 556{
555 int i; 557 int i;
556 558
557 clk_register(&cp_clcd_clk); 559 for (i = 0; i < ARRAY_SIZE(cp_lookups); i++)
558 clk_register(&cp_mmci_clk); 560 clkdev_add(&cp_lookups[i]);
559 561
560 platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); 562 platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
561 563
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index ca8e20538157..a3e0e1989a6b 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -12,6 +12,7 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14 14
15#include <asm/clkdev.h>
15#include <mach/pxa2xx-regs.h> 16#include <mach/pxa2xx-regs.h>
16#include <mach/pxa2xx-gpio.h> 17#include <mach/pxa2xx-gpio.h>
17#include <mach/hardware.h> 18#include <mach/hardware.h>
@@ -20,45 +21,8 @@
20#include "generic.h" 21#include "generic.h"
21#include "clock.h" 22#include "clock.h"
22 23
23static LIST_HEAD(clocks);
24static DEFINE_MUTEX(clocks_mutex);
25static DEFINE_SPINLOCK(clocks_lock); 24static DEFINE_SPINLOCK(clocks_lock);
26 25
27static struct clk *clk_lookup(struct device *dev, const char *id)
28{
29 struct clk *p;
30
31 list_for_each_entry(p, &clocks, node)
32 if (strcmp(id, p->name) == 0 && p->dev == dev)
33 return p;
34
35 return NULL;
36}
37
38struct clk *clk_get(struct device *dev, const char *id)
39{
40 struct clk *p, *clk = ERR_PTR(-ENOENT);
41
42 mutex_lock(&clocks_mutex);
43 p = clk_lookup(dev, id);
44 if (!p)
45 p = clk_lookup(NULL, id);
46 if (p)
47 clk = p;
48 mutex_unlock(&clocks_mutex);
49
50 if (!IS_ERR(clk) && clk->ops == NULL)
51 clk = clk->other;
52
53 return clk;
54}
55EXPORT_SYMBOL(clk_get);
56
57void clk_put(struct clk *clk)
58{
59}
60EXPORT_SYMBOL(clk_put);
61
62int clk_enable(struct clk *clk) 26int clk_enable(struct clk *clk)
63{ 27{
64 unsigned long flags; 28 unsigned long flags;
@@ -116,37 +80,27 @@ const struct clkops clk_cken_ops = {
116 .disable = clk_cken_disable, 80 .disable = clk_cken_disable,
117}; 81};
118 82
119void clks_register(struct clk *clks, size_t num) 83void clks_register(struct clk_lookup *clks, size_t num)
120{ 84{
121 int i; 85 int i;
122 86
123 mutex_lock(&clocks_mutex);
124 for (i = 0; i < num; i++) 87 for (i = 0; i < num; i++)
125 list_add(&clks[i].node, &clocks); 88 clkdev_add(&clks[i]);
126 mutex_unlock(&clocks_mutex);
127} 89}
128 90
129int clk_add_alias(char *alias, struct device *alias_dev, char *id, 91int clk_add_alias(char *alias, struct device *alias_dev, char *id,
130 struct device *dev) 92 struct device *dev)
131{ 93{
132 struct clk *r = clk_lookup(dev, id); 94 struct clk *r = clk_get(dev, id);
133 struct clk *new; 95 struct clk_lookup *l;
134 96
135 if (!r) 97 if (!r)
136 return -ENODEV; 98 return -ENODEV;
137 99
138 new = kzalloc(sizeof(struct clk), GFP_KERNEL); 100 l = clkdev_alloc(r, alias, alias_dev ? dev_name(alias_dev) : NULL);
139 101 clk_put(r);
140 if (!new) 102 if (!l)
141 return -ENOMEM; 103 return -ENODEV;
142 104 clkdev_add(l);
143 new->name = alias;
144 new->dev = alias_dev;
145 new->other = r;
146
147 mutex_lock(&clocks_mutex);
148 list_add(&new->node, &clocks);
149 mutex_unlock(&clocks_mutex);
150
151 return 0; 105 return 0;
152} 106}
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index 73be795fe3bf..4e9c613c6767 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -1,6 +1,4 @@
1#include <linux/list.h> 1#include <asm/clkdev.h>
2
3struct clk;
4 2
5struct clkops { 3struct clkops {
6 void (*enable)(struct clk *); 4 void (*enable)(struct clk *);
@@ -9,9 +7,6 @@ struct clkops {
9}; 7};
10 8
11struct clk { 9struct clk {
12 struct list_head node;
13 const char *name;
14 struct device *dev;
15 const struct clkops *ops; 10 const struct clkops *ops;
16 unsigned long rate; 11 unsigned long rate;
17 unsigned int cken; 12 unsigned int cken;
@@ -20,41 +15,31 @@ struct clk {
20 struct clk *other; 15 struct clk *other;
21}; 16};
22 17
23#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \ 18#define INIT_CLKREG(_clk,_devname,_conname) \
24 { \ 19 { \
25 .name = _name, \ 20 .clk = _clk, \
26 .dev = _dev, \ 21 .dev_id = _devname, \
22 .con_id = _conname, \
23 }
24
25#define DEFINE_CKEN(_name, _cken, _rate, _delay) \
26struct clk clk_##_name = { \
27 .ops = &clk_cken_ops, \ 27 .ops = &clk_cken_ops, \
28 .rate = _rate, \ 28 .rate = _rate, \
29 .cken = CKEN_##_cken, \ 29 .cken = CKEN_##_cken, \
30 .delay = _delay, \ 30 .delay = _delay, \
31 } 31 }
32 32
33#define INIT_CK(_name, _cken, _ops, _dev) \ 33#define DEFINE_CK(_name, _cken, _ops) \
34 { \ 34struct clk clk_##_name = { \
35 .name = _name, \
36 .dev = _dev, \
37 .ops = _ops, \ 35 .ops = _ops, \
38 .cken = CKEN_##_cken, \ 36 .cken = CKEN_##_cken, \
39 } 37 }
40 38
41/* 39#define DEFINE_CLK(_name, _ops, _rate, _delay) \
42 * This is a placeholder to alias one clock device+name pair 40struct clk clk_##_name = { \
43 * to another struct clk. 41 .ops = _ops, \
44 */ 42 .rate = _rate, \
45#define INIT_CKOTHER(_name, _other, _dev) \
46 { \
47 .name = _name, \
48 .dev = _dev, \
49 .other = _other, \
50 }
51
52#define INIT_CLK(_name, _ops, _rate, _delay, _dev) \
53 { \
54 .name = _name, \
55 .dev = _dev, \
56 .ops = _ops, \
57 .rate = _rate, \
58 .delay = _delay, \ 43 .delay = _delay, \
59 } 44 }
60 45
@@ -64,20 +49,16 @@ void clk_cken_enable(struct clk *clk);
64void clk_cken_disable(struct clk *clk); 49void clk_cken_disable(struct clk *clk);
65 50
66#ifdef CONFIG_PXA3xx 51#ifdef CONFIG_PXA3xx
67#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \ 52#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \
68 { \ 53struct clk clk_##_name = { \
69 .name = _name, \
70 .dev = _dev, \
71 .ops = &clk_pxa3xx_cken_ops, \ 54 .ops = &clk_pxa3xx_cken_ops, \
72 .rate = _rate, \ 55 .rate = _rate, \
73 .cken = CKEN_##_cken, \ 56 .cken = CKEN_##_cken, \
74 .delay = _delay, \ 57 .delay = _delay, \
75 } 58 }
76 59
77#define PXA3xx_CK(_name, _cken, _ops, _dev) \ 60#define DEFINE_PXA3_CK(_name, _cken, _ops) \
78 { \ 61struct clk clk_##_name = { \
79 .name = _name, \
80 .dev = _dev, \
81 .ops = _ops, \ 62 .ops = _ops, \
82 .cken = CKEN_##_cken, \ 63 .cken = CKEN_##_cken, \
83 } 64 }
@@ -87,7 +68,7 @@ extern void clk_pxa3xx_cken_enable(struct clk *);
87extern void clk_pxa3xx_cken_disable(struct clk *); 68extern void clk_pxa3xx_cken_disable(struct clk *);
88#endif 69#endif
89 70
90void clks_register(struct clk *clks, size_t num); 71void clks_register(struct clk_lookup *clks, size_t num);
91int clk_add_alias(char *alias, struct device *alias_dev, char *id, 72int clk_add_alias(char *alias, struct device *alias_dev, char *id,
92 struct device *dev); 73 struct device *dev);
93 74
diff --git a/arch/arm/mach-pxa/include/mach/clkdev.h b/arch/arm/mach-pxa/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c
index 74e2ead8cee8..3ca7ffc6904b 100644
--- a/arch/arm/mach-pxa/pwm.c
+++ b/arch/arm/mach-pxa/pwm.c
@@ -173,7 +173,7 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev,
173 return ERR_PTR(-ENOMEM); 173 return ERR_PTR(-ENOMEM);
174 } 174 }
175 175
176 pwm->clk = clk_get(&pdev->dev, "PWMCLK"); 176 pwm->clk = clk_get(&pdev->dev, NULL);
177 if (IS_ERR(pwm->clk)) { 177 if (IS_ERR(pwm->clk)) {
178 ret = PTR_ERR(pwm->clk); 178 ret = PTR_ERR(pwm->clk);
179 goto err_free; 179 goto err_free;
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 25d17a1dab78..344b3282caf9 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -167,36 +167,51 @@ static const struct clkops clk_pxa25x_gpio11_ops = {
167 * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz 167 * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
168 * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly) 168 * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
169 */ 169 */
170static struct clk pxa25x_hwuart_clk = 170static DEFINE_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
171 INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev) 171
172; 172static struct clk_lookup pxa25x_hwuart_clkreg =
173 INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
173 174
174/* 175/*
175 * PXA 2xx clock declarations. 176 * PXA 2xx clock declarations.
176 */ 177 */
177static struct clk pxa25x_clks[] = { 178static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops);
178 INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev), 179static DEFINE_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
179 INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev), 180static DEFINE_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
180 INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev), 181static DEFINE_CKEN(pxa25x_stuart, STUART, 14745600, 1);
181 INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL), 182static DEFINE_CKEN(pxa25x_usb, USB, 47923000, 5);
182 INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa25x_device_udc.dev), 183static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0);
183 INIT_CLK("GPIO11_CLK", &clk_pxa25x_gpio11_ops, 3686400, 0, NULL), 184static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0);
184 INIT_CLK("GPIO12_CLK", &clk_pxa25x_gpio12_ops, 32768, 0, NULL), 185static DEFINE_CKEN(pxa25x_mmc, MMC, 19169000, 0);
185 INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev), 186static DEFINE_CKEN(pxa25x_i2c, I2C, 31949000, 0);
186 INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev), 187static DEFINE_CKEN(pxa25x_ssp, SSP, 3686400, 0);
187 188static DEFINE_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
188 INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), 189static DEFINE_CKEN(pxa25x_assp, ASSP, 3686400, 0);
189 INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), 190static DEFINE_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
190 INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), 191static DEFINE_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
191 INIT_CKEN("PWMCLK", PWM0, 3686400, 0, &pxa25x_device_pwm0.dev), 192static DEFINE_CKEN(pxa25x_ac97, AC97, 24576000, 0);
192 INIT_CKEN("PWMCLK", PWM1, 3686400, 0, &pxa25x_device_pwm1.dev), 193static DEFINE_CKEN(pxa25x_i2s, I2S, 14745600, 0);
193 194static DEFINE_CKEN(pxa25x_ficp, FICP, 47923000, 0);
194 INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), 195
195 196static struct clk_lookup pxa25x_clkregs[] = {
196 /* 197 INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL),
197 INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), 198 INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL),
198 */ 199 INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL),
199 INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), 200 INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL),
201 INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL),
202 INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL),
203 INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL),
204 INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL),
205 INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL),
206 INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL),
207 INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL),
208 INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL),
209 INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL),
210 INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"),
211 INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"),
212 INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"),
213 INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
214 INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
200}; 215};
201 216
202#ifdef CONFIG_PM 217#ifdef CONFIG_PM
@@ -336,7 +351,7 @@ static int __init pxa25x_init(void)
336 351
337 reset_status = RCSR; 352 reset_status = RCSR;
338 353
339 clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks)); 354 clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
340 355
341 if ((ret = pxa_init_dma(16))) 356 if ((ret = pxa_init_dma(16)))
342 return ret; 357 return ret;
@@ -357,7 +372,7 @@ static int __init pxa25x_init(void)
357 372
358 /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ 373 /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
359 if (cpu_is_pxa255() || cpu_is_pxa26x()) { 374 if (cpu_is_pxa255() || cpu_is_pxa26x()) {
360 clks_register(&pxa25x_hwuart_clk, 1); 375 clks_register(&pxa25x_hwuart_clkreg, 1);
361 ret = platform_device_register(&pxa_device_hwuart); 376 ret = platform_device_register(&pxa_device_hwuart);
362 } 377 }
363 378
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 3e4ab2279c99..15c8e5b9f9bc 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -144,40 +144,59 @@ static const struct clkops clk_pxa27x_lcd_ops = {
144 .getrate = clk_pxa27x_lcd_getrate, 144 .getrate = clk_pxa27x_lcd_getrate,
145}; 145};
146 146
147static struct clk pxa27x_clks[] = { 147static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops);
148 INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev), 148static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops);
149 INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL), 149static DEFINE_CKEN(pxa27x_ffuart, FFUART, 14857000, 1);
150 150static DEFINE_CKEN(pxa27x_btuart, BTUART, 14857000, 1);
151 INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev), 151static DEFINE_CKEN(pxa27x_stuart, STUART, 14857000, 1);
152 INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev), 152static DEFINE_CKEN(pxa27x_i2s, I2S, 14682000, 0);
153 INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL), 153static DEFINE_CKEN(pxa27x_i2c, I2C, 32842000, 0);
154 154static DEFINE_CKEN(pxa27x_usb, USB, 48000000, 5);
155 INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev), 155static DEFINE_CKEN(pxa27x_mmc, MMC, 19500000, 0);
156 INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev), 156static DEFINE_CKEN(pxa27x_ficp, FICP, 48000000, 0);
157 INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa27x_device_udc.dev), 157static DEFINE_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0);
158 INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev), 158static DEFINE_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0);
159 INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev), 159static DEFINE_CKEN(pxa27x_keypad, KEYPAD, 32768, 0);
160 160static DEFINE_CKEN(pxa27x_ssp1, SSP1, 13000000, 0);
161 INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev), 161static DEFINE_CKEN(pxa27x_ssp2, SSP2, 13000000, 0);
162 INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev), 162static DEFINE_CKEN(pxa27x_ssp3, SSP3, 13000000, 0);
163 INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev), 163static DEFINE_CKEN(pxa27x_pwm0, PWM0, 13000000, 0);
164 164static DEFINE_CKEN(pxa27x_pwm1, PWM1, 13000000, 0);
165 INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), 165static DEFINE_CKEN(pxa27x_ac97, AC97, 24576000, 0);
166 INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), 166static DEFINE_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0);
167 INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), 167static DEFINE_CKEN(pxa27x_msl, MSL, 48000000, 0);
168 INIT_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), 168static DEFINE_CKEN(pxa27x_usim, USIM, 48000000, 0);
169 INIT_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), 169static DEFINE_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0);
170 170static DEFINE_CKEN(pxa27x_im, IM, 0, 0);
171 INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), 171static DEFINE_CKEN(pxa27x_memc, MEMC, 0, 0);
172 INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), 172
173 173static struct clk_lookup pxa27x_clkregs[] = {
174 /* 174 INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL),
175 INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), 175 INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL),
176 INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), 176 INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL),
177 INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), 177 INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL),
178 INIT_CKEN("IMCLK", IM, 0, 0, NULL), 178 INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL),
179 INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL), 179 INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL),
180 */ 180 INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL),
181 INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL),
182 INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL),
183 INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"),
184 INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"),
185 INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL),
186 INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL),
187 INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL),
188 INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL),
189 INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL),
190 INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL),
191 INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL),
192 INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL),
193 INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"),
194 INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"),
195 INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"),
196 INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"),
197 INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"),
198 INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
199 INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
181}; 200};
182 201
183#ifdef CONFIG_PM 202#ifdef CONFIG_PM
@@ -380,7 +399,7 @@ static int __init pxa27x_init(void)
380 399
381 reset_status = RCSR; 400 reset_status = RCSR;
382 401
383 clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); 402 clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
384 403
385 if ((ret = pxa_init_dma(32))) 404 if ((ret = pxa_init_dma(32)))
386 return ret; 405 return ret;
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 9adc7fc4618a..f735e58e6669 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -85,14 +85,16 @@ static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
85 MFP_ADDR_END, 85 MFP_ADDR_END,
86}; 86};
87 87
88static struct clk common_clks[] = { 88static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0);
89 PXA3xx_CKEN("NANDCLK", NAND, 156000000, 0, &pxa3xx_device_nand.dev), 89
90static struct clk_lookup common_clkregs[] = {
91 INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", "NANDCLK"),
90}; 92};
91 93
92static struct clk pxa310_clks[] = { 94static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
93#ifdef CONFIG_CPU_PXA310 95
94 PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev), 96static struct clk_lookup pxa310_clkregs[] = {
95#endif 97 INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", "MMCCLK"),
96}; 98};
97 99
98static int __init pxa300_init(void) 100static int __init pxa300_init(void)
@@ -100,12 +102,12 @@ static int __init pxa300_init(void)
100 if (cpu_is_pxa300() || cpu_is_pxa310()) { 102 if (cpu_is_pxa300() || cpu_is_pxa310()) {
101 pxa3xx_init_mfp(); 103 pxa3xx_init_mfp();
102 pxa3xx_mfp_init_addr(pxa300_mfp_addr_map); 104 pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
103 clks_register(ARRAY_AND_SIZE(common_clks)); 105 clks_register(ARRAY_AND_SIZE(common_clkregs));
104 } 106 }
105 107
106 if (cpu_is_pxa310()) { 108 if (cpu_is_pxa310()) {
107 pxa3xx_mfp_init_addr(pxa310_mfp_addr_map); 109 pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
108 clks_register(ARRAY_AND_SIZE(pxa310_clks)); 110 clks_register(ARRAY_AND_SIZE(pxa310_clkregs));
109 } 111 }
110 112
111 return 0; 113 return 0;
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 016eb18f01a3..effe408c186f 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -80,8 +80,10 @@ static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
80 MFP_ADDR_END, 80 MFP_ADDR_END,
81}; 81};
82 82
83static struct clk pxa320_clks[] = { 83static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0);
84 PXA3xx_CKEN("NANDCLK", NAND, 104000000, 0, &pxa3xx_device_nand.dev), 84
85static struct clk_lookup pxa320_clkregs[] = {
86 INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", "NANDCLK"),
85}; 87};
86 88
87static int __init pxa320_init(void) 89static int __init pxa320_init(void)
@@ -89,7 +91,7 @@ static int __init pxa320_init(void)
89 if (cpu_is_pxa320()) { 91 if (cpu_is_pxa320()) {
90 pxa3xx_init_mfp(); 92 pxa3xx_init_mfp();
91 pxa3xx_mfp_init_addr(pxa320_mfp_addr_map); 93 pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
92 clks_register(ARRAY_AND_SIZE(pxa320_clks)); 94 clks_register(ARRAY_AND_SIZE(pxa320_clkregs));
93 } 95 }
94 96
95 return 0; 97 return 0;
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index b3cd5d0b0f35..b7e53829d376 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -216,43 +216,58 @@ static const struct clkops clk_dummy_ops = {
216 .disable = clk_dummy_disable, 216 .disable = clk_dummy_disable,
217}; 217};
218 218
219static struct clk pxa3xx_clks[] = { 219static struct clk clk_pxa3xx_pout = {
220 { 220 .ops = &clk_pout_ops,
221 .name = "CLK_POUT", 221 .rate = 13000000,
222 .ops = &clk_pout_ops, 222 .delay = 70,
223 .rate = 13000000, 223};
224 .delay = 70,
225 },
226
227 /* Power I2C clock is always on */
228 {
229 .name = "I2CCLK",
230 .ops = &clk_dummy_ops,
231 .dev = &pxa3xx_device_i2c_power.dev,
232 },
233
234 PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
235 PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
236 PXA3xx_CK("AC97CLK", AC97, &clk_pxa3xx_ac97_ops, NULL),
237
238 PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
239 PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
240 PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
241
242 PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
243 PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa27x_device_udc.dev),
244 PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
245 PXA3xx_CKEN("KBDCLK", KEYPAD, 32768, 0, &pxa27x_device_keypad.dev),
246 224
247 PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), 225static struct clk clk_dummy = {
248 PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), 226 .ops = &clk_dummy_ops,
249 PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), 227};
250 PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
251 PXA3xx_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev),
252 PXA3xx_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev),
253 228
254 PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), 229static DEFINE_PXA3_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
255 PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), 230static DEFINE_PXA3_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops);
231static DEFINE_PXA3_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops);
232static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
233static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
234static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
235static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0);
236static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5);
237static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0);
238static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0);
239static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0);
240static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0);
241static DEFINE_PXA3_CKEN(pxa3xx_ssp3, SSP3, 13000000, 0);
242static DEFINE_PXA3_CKEN(pxa3xx_ssp4, SSP4, 13000000, 0);
243static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0);
244static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0);
245static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0);
246static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0);
247
248static struct clk_lookup pxa3xx_clkregs[] = {
249 INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
250 /* Power I2C clock is always on */
251 INIT_CLKREG(&clk_dummy, "pxa2xx-i2c.1", NULL),
252 INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
253 INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
254 INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
255 INIT_CLKREG(&clk_pxa3xx_ffuart, "pxa2xx-uart.0", NULL),
256 INIT_CLKREG(&clk_pxa3xx_btuart, "pxa2xx-uart.1", NULL),
257 INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-uart.2", NULL),
258 INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-ir", "UARTCLK"),
259 INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
260 INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
261 INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
262 INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
263 INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
264 INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
265 INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa27x-ssp.2", NULL),
266 INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa27x-ssp.3", NULL),
267 INIT_CLKREG(&clk_pxa3xx_pwm0, "pxa27x-pwm.0", NULL),
268 INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL),
269 INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
270 INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
256}; 271};
257 272
258#ifdef CONFIG_PM 273#ifdef CONFIG_PM
@@ -595,7 +610,7 @@ static int __init pxa3xx_init(void)
595 */ 610 */
596 ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S); 611 ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
597 612
598 clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); 613 clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
599 614
600 if ((ret = pxa_init_dma(32))) 615 if ((ret = pxa_init_dma(32)))
601 return ret; 616 return ret;
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 2c31ec725688..6f42004db3ed 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -356,7 +356,7 @@ static int __devinit ssp_probe(struct platform_device *pdev, int type)
356 } 356 }
357 ssp->pdev = pdev; 357 ssp->pdev = pdev;
358 358
359 ssp->clk = clk_get(&pdev->dev, "SSPCLK"); 359 ssp->clk = clk_get(&pdev->dev, NULL);
360 if (IS_ERR(ssp->clk)) { 360 if (IS_ERR(ssp->clk)) {
361 ret = PTR_ERR(ssp->clk); 361 ret = PTR_ERR(ssp->clk);
362 goto err_free; 362 goto err_free;
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
index 3347c4236a60..a7043115de72 100644
--- a/arch/arm/mach-realview/clock.c
+++ b/arch/arm/mach-realview/clock.c
@@ -10,9 +10,11 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/device.h>
13#include <linux/list.h> 14#include <linux/list.h>
14#include <linux/errno.h> 15#include <linux/errno.h>
15#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/string.h>
16#include <linux/clk.h> 18#include <linux/clk.h>
17#include <linux/mutex.h> 19#include <linux/mutex.h>
18 20
@@ -20,32 +22,6 @@
20 22
21#include "clock.h" 23#include "clock.h"
22 24
23static LIST_HEAD(clocks);
24static DEFINE_MUTEX(clocks_mutex);
25
26struct clk *clk_get(struct device *dev, const char *id)
27{
28 struct clk *p, *clk = ERR_PTR(-ENOENT);
29
30 mutex_lock(&clocks_mutex);
31 list_for_each_entry(p, &clocks, node) {
32 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
33 clk = p;
34 break;
35 }
36 }
37 mutex_unlock(&clocks_mutex);
38
39 return clk;
40}
41EXPORT_SYMBOL(clk_get);
42
43void clk_put(struct clk *clk)
44{
45 module_put(clk->owner);
46}
47EXPORT_SYMBOL(clk_put);
48
49int clk_enable(struct clk *clk) 25int clk_enable(struct clk *clk)
50{ 26{
51 return 0; 27 return 0;
@@ -65,7 +41,9 @@ EXPORT_SYMBOL(clk_get_rate);
65 41
66long clk_round_rate(struct clk *clk, unsigned long rate) 42long clk_round_rate(struct clk *clk, unsigned long rate)
67{ 43{
68 return rate; 44 struct icst307_vco vco;
45 vco = icst307_khz_to_vco(clk->params, rate / 1000);
46 return icst307_khz(clk->params, vco) * 1000;
69} 47}
70EXPORT_SYMBOL(clk_round_rate); 48EXPORT_SYMBOL(clk_round_rate);
71 49
@@ -78,57 +56,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
78 56
79 vco = icst307_khz_to_vco(clk->params, rate / 1000); 57 vco = icst307_khz_to_vco(clk->params, rate / 1000);
80 clk->rate = icst307_khz(clk->params, vco) * 1000; 58 clk->rate = icst307_khz(clk->params, vco) * 1000;
81
82 printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
83 clk->name, vco.s, vco.r, vco.v);
84
85 clk->setvco(clk, vco); 59 clk->setvco(clk, vco);
86 ret = 0; 60 ret = 0;
87 } 61 }
88 return ret; 62 return ret;
89} 63}
90EXPORT_SYMBOL(clk_set_rate); 64EXPORT_SYMBOL(clk_set_rate);
91
92/*
93 * These are fixed clocks.
94 */
95static struct clk kmi_clk = {
96 .name = "KMIREFCLK",
97 .rate = 24000000,
98};
99
100static struct clk uart_clk = {
101 .name = "UARTCLK",
102 .rate = 24000000,
103};
104
105static struct clk mmci_clk = {
106 .name = "MCLK",
107 .rate = 24000000,
108};
109
110int clk_register(struct clk *clk)
111{
112 mutex_lock(&clocks_mutex);
113 list_add(&clk->node, &clocks);
114 mutex_unlock(&clocks_mutex);
115 return 0;
116}
117EXPORT_SYMBOL(clk_register);
118
119void clk_unregister(struct clk *clk)
120{
121 mutex_lock(&clocks_mutex);
122 list_del(&clk->node);
123 mutex_unlock(&clocks_mutex);
124}
125EXPORT_SYMBOL(clk_unregister);
126
127static int __init clk_init(void)
128{
129 clk_register(&kmi_clk);
130 clk_register(&uart_clk);
131 clk_register(&mmci_clk);
132 return 0;
133}
134arch_initcall(clk_init);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
index dadba695e181..ebbb0f06b600 100644
--- a/arch/arm/mach-realview/clock.h
+++ b/arch/arm/mach-realview/clock.h
@@ -12,14 +12,8 @@ struct module;
12struct icst307_params; 12struct icst307_params;
13 13
14struct clk { 14struct clk {
15 struct list_head node;
16 unsigned long rate; 15 unsigned long rate;
17 struct module *owner;
18 const char *name;
19 const struct icst307_params *params; 16 const struct icst307_params *params;
20 void *data; 17 void *data;
21 void (*setvco)(struct clk *, struct icst307_vco vco); 18 void (*setvco)(struct clk *, struct icst307_vco vco);
22}; 19};
23
24int clk_register(struct clk *clk);
25void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 2f04d54711e7..2491374818e9 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -29,6 +29,7 @@
29#include <linux/clockchips.h> 29#include <linux/clockchips.h>
30#include <linux/io.h> 30#include <linux/io.h>
31 31
32#include <asm/clkdev.h>
32#include <asm/system.h> 33#include <asm/system.h>
33#include <mach/hardware.h> 34#include <mach/hardware.h>
34#include <asm/irq.h> 35#include <asm/irq.h>
@@ -188,13 +189,60 @@ static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
188 writel(0, sys_lock); 189 writel(0, sys_lock);
189} 190}
190 191
191struct clk realview_clcd_clk = { 192static struct clk oscvco_clk = {
192 .name = "CLCDCLK",
193 .params = &realview_oscvco_params, 193 .params = &realview_oscvco_params,
194 .setvco = realview_oscvco_set, 194 .setvco = realview_oscvco_set,
195}; 195};
196 196
197/* 197/*
198 * These are fixed clocks.
199 */
200static struct clk ref24_clk = {
201 .rate = 24000000,
202};
203
204static struct clk_lookup lookups[] = {
205 { /* UART0 */
206 .dev_id = "dev:f1",
207 .clk = &ref24_clk,
208 }, { /* UART1 */
209 .dev_id = "dev:f2",
210 .clk = &ref24_clk,
211 }, { /* UART2 */
212 .dev_id = "dev:f3",
213 .clk = &ref24_clk,
214 }, { /* UART3 */
215 .dev_id = "fpga:09",
216 .clk = &ref24_clk,
217 }, { /* KMI0 */
218 .dev_id = "fpga:06",
219 .clk = &ref24_clk,
220 }, { /* KMI1 */
221 .dev_id = "fpga:07",
222 .clk = &ref24_clk,
223 }, { /* MMC0 */
224 .dev_id = "fpga:05",
225 .clk = &ref24_clk,
226 }, { /* EB:CLCD */
227 .dev_id = "dev:20",
228 .clk = &oscvco_clk,
229 }, { /* PB:CLCD */
230 .dev_id = "issp:20",
231 .clk = &oscvco_clk,
232 }
233};
234
235static int __init clk_init(void)
236{
237 int i;
238
239 for (i = 0; i < ARRAY_SIZE(lookups); i++)
240 clkdev_add(&lookups[i]);
241 return 0;
242}
243arch_initcall(clk_init);
244
245/*
198 * CLCD support. 246 * CLCD support.
199 */ 247 */
200#define SYS_CLCD_NLCDIOON (1 << 2) 248#define SYS_CLCD_NLCDIOON (1 << 2)
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 3cea92c70d8f..614e8cb31713 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -48,7 +48,6 @@ extern struct platform_device realview_flash_device;
48extern struct platform_device realview_i2c_device; 48extern struct platform_device realview_i2c_device;
49extern struct mmc_platform_data realview_mmc0_plat_data; 49extern struct mmc_platform_data realview_mmc0_plat_data;
50extern struct mmc_platform_data realview_mmc1_plat_data; 50extern struct mmc_platform_data realview_mmc1_plat_data;
51extern struct clk realview_clcd_clk;
52extern struct clcd_board clcd_plat_data; 51extern struct clcd_board clcd_plat_data;
53extern void __iomem *gic_cpu_base_addr; 52extern void __iomem *gic_cpu_base_addr;
54#ifdef CONFIG_LOCAL_TIMERS 53#ifdef CONFIG_LOCAL_TIMERS
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index eb829eb1ebe2..3420e2e719e6 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -372,8 +372,6 @@ static void __init realview_eb_init(void)
372#endif 372#endif
373 } 373 }
374 374
375 clk_register(&realview_clcd_clk);
376
377 realview_flash_register(&realview_eb_flash_resource, 1); 375 realview_flash_register(&realview_eb_flash_resource, 1);
378 platform_device_register(&realview_i2c_device); 376 platform_device_register(&realview_i2c_device);
379 eth_device_register(); 377 eth_device_register();
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index cccdb3eb90fe..0481416d37c9 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -265,8 +265,6 @@ static void __init realview_pb1176_init(void)
265 l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff); 265 l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
266#endif 266#endif
267 267
268 clk_register(&realview_clcd_clk);
269
270 realview_flash_register(&realview_pb1176_flash_resource, 1); 268 realview_flash_register(&realview_pb1176_flash_resource, 1);
271 platform_device_register(&realview_pb1176_smsc911x_device); 269 platform_device_register(&realview_pb1176_smsc911x_device);
272 270
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 8b863148ec18..6197dd8e8edf 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -312,8 +312,6 @@ static void __init realview_pb11mp_init(void)
312 l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff); 312 l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
313#endif 313#endif
314 314
315 clk_register(&realview_clcd_clk);
316
317 realview_flash_register(realview_pb11mp_flash_resource, 315 realview_flash_register(realview_pb11mp_flash_resource,
318 ARRAY_SIZE(realview_pb11mp_flash_resource)); 316 ARRAY_SIZE(realview_pb11mp_flash_resource));
319 platform_device_register(&realview_pb11mp_smsc911x_device); 317 platform_device_register(&realview_pb11mp_smsc911x_device);
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 43c30f84abf2..dab3c6347a8f 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -3,6 +3,7 @@
3 */ 3 */
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/kernel.h> 5#include <linux/kernel.h>
6#include <linux/device.h>
6#include <linux/list.h> 7#include <linux/list.h>
7#include <linux/errno.h> 8#include <linux/errno.h>
8#include <linux/err.h> 9#include <linux/err.h>
@@ -14,36 +15,39 @@
14#include <mach/hardware.h> 15#include <mach/hardware.h>
15 16
16/* 17/*
17 * Very simple clock implementation - we only have one clock to 18 * Very simple clock implementation - we only have one clock to deal with.
18 * deal with at the moment, so we only match using the "name".
19 */ 19 */
20struct clk { 20struct clk {
21 struct list_head node;
22 unsigned long rate;
23 const char *name;
24 unsigned int enabled; 21 unsigned int enabled;
25 void (*enable)(void);
26 void (*disable)(void);
27}; 22};
28 23
29static LIST_HEAD(clocks); 24static void clk_gpio27_enable(void)
30static DEFINE_MUTEX(clocks_mutex); 25{
26 /*
27 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
28 * (SA-1110 Developer's Manual, section 9.1.2.1)
29 */
30 GAFR |= GPIO_32_768kHz;
31 GPDR |= GPIO_32_768kHz;
32 TUCR = TUCR_3_6864MHz;
33}
34
35static void clk_gpio27_disable(void)
36{
37 TUCR = 0;
38 GPDR &= ~GPIO_32_768kHz;
39 GAFR &= ~GPIO_32_768kHz;
40}
41
42static struct clk clk_gpio27;
43
31static DEFINE_SPINLOCK(clocks_lock); 44static DEFINE_SPINLOCK(clocks_lock);
32 45
33struct clk *clk_get(struct device *dev, const char *id) 46struct clk *clk_get(struct device *dev, const char *id)
34{ 47{
35 struct clk *p, *clk = ERR_PTR(-ENOENT); 48 const char *devname = dev_name(dev);
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 49
46 return clk; 50 return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
47} 51}
48EXPORT_SYMBOL(clk_get); 52EXPORT_SYMBOL(clk_get);
49 53
@@ -58,7 +62,7 @@ int clk_enable(struct clk *clk)
58 62
59 spin_lock_irqsave(&clocks_lock, flags); 63 spin_lock_irqsave(&clocks_lock, flags);
60 if (clk->enabled++ == 0) 64 if (clk->enabled++ == 0)
61 clk->enable(); 65 clk_gpio27_enable();
62 spin_unlock_irqrestore(&clocks_lock, flags); 66 spin_unlock_irqrestore(&clocks_lock, flags);
63 return 0; 67 return 0;
64} 68}
@@ -72,63 +76,13 @@ void clk_disable(struct clk *clk)
72 76
73 spin_lock_irqsave(&clocks_lock, flags); 77 spin_lock_irqsave(&clocks_lock, flags);
74 if (--clk->enabled == 0) 78 if (--clk->enabled == 0)
75 clk->disable(); 79 clk_gpio27_disable();
76 spin_unlock_irqrestore(&clocks_lock, flags); 80 spin_unlock_irqrestore(&clocks_lock, flags);
77} 81}
78EXPORT_SYMBOL(clk_disable); 82EXPORT_SYMBOL(clk_disable);
79 83
80unsigned long clk_get_rate(struct clk *clk) 84unsigned long clk_get_rate(struct clk *clk)
81{ 85{
82 return clk->rate; 86 return 3686400;
83} 87}
84EXPORT_SYMBOL(clk_get_rate); 88EXPORT_SYMBOL(clk_get_rate);
85
86
87static 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
98static void clk_gpio27_disable(void)
99{
100 TUCR = 0;
101 GPDR &= ~GPIO_32_768kHz;
102 GAFR &= ~GPIO_32_768kHz;
103}
104
105static struct clk clk_gpio27 = {
106 .name = "SA1111_CLK",
107 .rate = 3686400,
108 .enable = clk_gpio27_enable,
109 .disable = clk_gpio27_disable,
110};
111
112int 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}
119EXPORT_SYMBOL(clk_register);
120
121void clk_unregister(struct clk *clk)
122{
123 mutex_lock(&clocks_mutex);
124 list_del(&clk->node);
125 mutex_unlock(&clocks_mutex);
126}
127EXPORT_SYMBOL(clk_unregister);
128
129static int __init clk_init(void)
130{
131 clk_register(&clk_gpio27);
132 return 0;
133}
134arch_initcall(clk_init);
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
index 58937f1fb38c..c50a44ea7ee6 100644
--- a/arch/arm/mach-versatile/clock.c
+++ b/arch/arm/mach-versatile/clock.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/device.h>
13#include <linux/list.h> 14#include <linux/list.h>
14#include <linux/errno.h> 15#include <linux/errno.h>
15#include <linux/err.h> 16#include <linux/err.h>
@@ -17,36 +18,11 @@
17#include <linux/clk.h> 18#include <linux/clk.h>
18#include <linux/mutex.h> 19#include <linux/mutex.h>
19 20
21#include <asm/clkdev.h>
20#include <asm/hardware/icst307.h> 22#include <asm/hardware/icst307.h>
21 23
22#include "clock.h" 24#include "clock.h"
23 25
24static LIST_HEAD(clocks);
25static DEFINE_MUTEX(clocks_mutex);
26
27struct clk *clk_get(struct device *dev, const char *id)
28{
29 struct clk *p, *clk = ERR_PTR(-ENOENT);
30
31 mutex_lock(&clocks_mutex);
32 list_for_each_entry(p, &clocks, node) {
33 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
34 clk = p;
35 break;
36 }
37 }
38 mutex_unlock(&clocks_mutex);
39
40 return clk;
41}
42EXPORT_SYMBOL(clk_get);
43
44void clk_put(struct clk *clk)
45{
46 module_put(clk->owner);
47}
48EXPORT_SYMBOL(clk_put);
49
50int clk_enable(struct clk *clk) 26int clk_enable(struct clk *clk)
51{ 27{
52 return 0; 28 return 0;
@@ -66,7 +42,9 @@ EXPORT_SYMBOL(clk_get_rate);
66 42
67long clk_round_rate(struct clk *clk, unsigned long rate) 43long clk_round_rate(struct clk *clk, unsigned long rate)
68{ 44{
69 return rate; 45 struct icst307_vco vco;
46 vco = icst307_khz_to_vco(clk->params, rate / 1000);
47 return icst307_khz(clk->params, vco) * 1000;
70} 48}
71EXPORT_SYMBOL(clk_round_rate); 49EXPORT_SYMBOL(clk_round_rate);
72 50
@@ -79,57 +57,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
79 57
80 vco = icst307_khz_to_vco(clk->params, rate / 1000); 58 vco = icst307_khz_to_vco(clk->params, rate / 1000);
81 clk->rate = icst307_khz(clk->params, vco) * 1000; 59 clk->rate = icst307_khz(clk->params, vco) * 1000;
82
83 printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
84 clk->name, vco.s, vco.r, vco.v);
85
86 clk->setvco(clk, vco); 60 clk->setvco(clk, vco);
87 ret = 0; 61 ret = 0;
88 } 62 }
89 return ret; 63 return ret;
90} 64}
91EXPORT_SYMBOL(clk_set_rate); 65EXPORT_SYMBOL(clk_set_rate);
92
93/*
94 * These are fixed clocks.
95 */
96static struct clk kmi_clk = {
97 .name = "KMIREFCLK",
98 .rate = 24000000,
99};
100
101static struct clk uart_clk = {
102 .name = "UARTCLK",
103 .rate = 24000000,
104};
105
106static struct clk mmci_clk = {
107 .name = "MCLK",
108 .rate = 24000000,
109};
110
111int clk_register(struct clk *clk)
112{
113 mutex_lock(&clocks_mutex);
114 list_add(&clk->node, &clocks);
115 mutex_unlock(&clocks_mutex);
116 return 0;
117}
118EXPORT_SYMBOL(clk_register);
119
120void clk_unregister(struct clk *clk)
121{
122 mutex_lock(&clocks_mutex);
123 list_del(&clk->node);
124 mutex_unlock(&clocks_mutex);
125}
126EXPORT_SYMBOL(clk_unregister);
127
128static int __init clk_init(void)
129{
130 clk_register(&kmi_clk);
131 clk_register(&uart_clk);
132 clk_register(&mmci_clk);
133 return 0;
134}
135arch_initcall(clk_init);
diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h
index 8b0b61dd17e4..03468fdc3e58 100644
--- a/arch/arm/mach-versatile/clock.h
+++ b/arch/arm/mach-versatile/clock.h
@@ -12,14 +12,9 @@ struct module;
12struct icst307_params; 12struct icst307_params;
13 13
14struct clk { 14struct clk {
15 struct list_head node;
16 unsigned long rate; 15 unsigned long rate;
17 struct module *owner;
18 const char *name;
19 const struct icst307_params *params; 16 const struct icst307_params *params;
17 u32 oscoff;
20 void *data; 18 void *data;
21 void (*setvco)(struct clk *, struct icst307_vco vco); 19 void (*setvco)(struct clk *, struct icst307_vco vco);
22}; 20};
23
24int clk_register(struct clk *clk);
25void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 565e0ba0d67e..df25aa138509 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -31,6 +31,7 @@
31#include <linux/cnt32_to_63.h> 31#include <linux/cnt32_to_63.h>
32#include <linux/io.h> 32#include <linux/io.h>
33 33
34#include <asm/clkdev.h>
34#include <asm/system.h> 35#include <asm/system.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36#include <asm/irq.h> 37#include <asm/irq.h>
@@ -373,22 +374,60 @@ static const struct icst307_params versatile_oscvco_params = {
373 374
374static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco) 375static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
375{ 376{
376 void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET; 377 void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
377 void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET; 378 void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET;
378 u32 val; 379 u32 val;
379 380
380 val = readl(sys_osc) & ~0x7ffff; 381 val = readl(sys + clk->oscoff) & ~0x7ffff;
381 val |= vco.v | (vco.r << 9) | (vco.s << 16); 382 val |= vco.v | (vco.r << 9) | (vco.s << 16);
382 383
383 writel(0xa05f, sys_lock); 384 writel(0xa05f, sys_lock);
384 writel(val, sys_osc); 385 writel(val, sys + clk->oscoff);
385 writel(0, sys_lock); 386 writel(0, sys_lock);
386} 387}
387 388
388static struct clk versatile_clcd_clk = { 389static struct clk osc4_clk = {
389 .name = "CLCDCLK",
390 .params = &versatile_oscvco_params, 390 .params = &versatile_oscvco_params,
391 .setvco = versatile_oscvco_set, 391 .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET,
392 .setvco = versatile_oscvco_set,
393};
394
395/*
396 * These are fixed clocks.
397 */
398static struct clk ref24_clk = {
399 .rate = 24000000,
400};
401
402static struct clk_lookup lookups[] __initdata = {
403 { /* UART0 */
404 .dev_id = "dev:f1",
405 .clk = &ref24_clk,
406 }, { /* UART1 */
407 .dev_id = "dev:f2",
408 .clk = &ref24_clk,
409 }, { /* UART2 */
410 .dev_id = "dev:f3",
411 .clk = &ref24_clk,
412 }, { /* UART3 */
413 .dev_id = "fpga:09",
414 .clk = &ref24_clk,
415 }, { /* KMI0 */
416 .dev_id = "fpga:06",
417 .clk = &ref24_clk,
418 }, { /* KMI1 */
419 .dev_id = "fpga:07",
420 .clk = &ref24_clk,
421 }, { /* MMC0 */
422 .dev_id = "fpga:05",
423 .clk = &ref24_clk,
424 }, { /* MMC1 */
425 .dev_id = "fpga:0b",
426 .clk = &ref24_clk,
427 }, { /* CLCD */
428 .dev_id = "dev:20",
429 .clk = &osc4_clk,
430 }
392}; 431};
393 432
394/* 433/*
@@ -786,7 +825,8 @@ void __init versatile_init(void)
786{ 825{
787 int i; 826 int i;
788 827
789 clk_register(&versatile_clcd_clk); 828 for (i = 0; i < ARRAY_SIZE(lookups); i++)
829 clkdev_add(&lookups[i]);
790 830
791 platform_device_register(&versatile_flash_device); 831 platform_device_register(&versatile_flash_device);
792 platform_device_register(&versatile_i2c_device); 832 platform_device_register(&versatile_i2c_device);
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_CLKDEV_H
2#define __ASM_MACH_CLKDEV_H
3
4#define __clk_get(clk) ({ 1; })
5#define __clk_put(clk) do { } while (0)
6
7#endif