Commit 71a06da08c1a100bba7221d140403aa7a6cdebe7
Committed by
Russell King
1 parent
d72fbdf01f
Exists in
master
and in
39 other branches
[ARM] versatile: convert to clkdev and lookup clocks by device name
People often point to the Integrator/Versatile/Realview implementations to justify using the consumer name as the sole selector for clocks. Eliminate this excuse by changing the Versatile implementation, so it provides a better example of how it should be done. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 5 changed files with 62 additions and 89 deletions Side-by-side Diff
arch/arm/Kconfig
arch/arm/mach-versatile/clock.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | */ |
11 | 11 | #include <linux/module.h> |
12 | 12 | #include <linux/kernel.h> |
13 | +#include <linux/device.h> | |
13 | 14 | #include <linux/list.h> |
14 | 15 | #include <linux/errno.h> |
15 | 16 | #include <linux/err.h> |
16 | 17 | |
... | ... | @@ -17,36 +18,11 @@ |
17 | 18 | #include <linux/clk.h> |
18 | 19 | #include <linux/mutex.h> |
19 | 20 | |
21 | +#include <asm/clkdev.h> | |
20 | 22 | #include <asm/hardware/icst307.h> |
21 | 23 | |
22 | 24 | #include "clock.h" |
23 | 25 | |
24 | -static LIST_HEAD(clocks); | |
25 | -static DEFINE_MUTEX(clocks_mutex); | |
26 | - | |
27 | -struct 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 | -} | |
42 | -EXPORT_SYMBOL(clk_get); | |
43 | - | |
44 | -void clk_put(struct clk *clk) | |
45 | -{ | |
46 | - module_put(clk->owner); | |
47 | -} | |
48 | -EXPORT_SYMBOL(clk_put); | |
49 | - | |
50 | 26 | int clk_enable(struct clk *clk) |
51 | 27 | { |
52 | 28 | return 0; |
... | ... | @@ -66,7 +42,9 @@ |
66 | 42 | |
67 | 43 | long 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 | } |
71 | 49 | EXPORT_SYMBOL(clk_round_rate); |
72 | 50 | |
73 | 51 | |
... | ... | @@ -79,58 +57,10 @@ |
79 | 57 | |
80 | 58 | vco = icst307_khz_to_vco(clk->params, rate / 1000); |
81 | 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 | 60 | clk->setvco(clk, vco); |
87 | 61 | ret = 0; |
88 | 62 | } |
89 | 63 | return ret; |
90 | 64 | } |
91 | 65 | EXPORT_SYMBOL(clk_set_rate); |
92 | - | |
93 | -/* | |
94 | - * These are fixed clocks. | |
95 | - */ | |
96 | -static struct clk kmi_clk = { | |
97 | - .name = "KMIREFCLK", | |
98 | - .rate = 24000000, | |
99 | -}; | |
100 | - | |
101 | -static struct clk uart_clk = { | |
102 | - .name = "UARTCLK", | |
103 | - .rate = 24000000, | |
104 | -}; | |
105 | - | |
106 | -static struct clk mmci_clk = { | |
107 | - .name = "MCLK", | |
108 | - .rate = 24000000, | |
109 | -}; | |
110 | - | |
111 | -int 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 | -} | |
118 | -EXPORT_SYMBOL(clk_register); | |
119 | - | |
120 | -void clk_unregister(struct clk *clk) | |
121 | -{ | |
122 | - mutex_lock(&clocks_mutex); | |
123 | - list_del(&clk->node); | |
124 | - mutex_unlock(&clocks_mutex); | |
125 | -} | |
126 | -EXPORT_SYMBOL(clk_unregister); | |
127 | - | |
128 | -static 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 | -} | |
135 | -arch_initcall(clk_init); |
arch/arm/mach-versatile/clock.h
... | ... | @@ -12,15 +12,10 @@ |
12 | 12 | struct icst307_params; |
13 | 13 | |
14 | 14 | struct clk { |
15 | - struct list_head node; | |
16 | 15 | unsigned long rate; |
17 | - struct module *owner; | |
18 | - const char *name; | |
19 | 16 | const struct icst307_params *params; |
17 | + u32 oscoff; | |
20 | 18 | void *data; |
21 | 19 | void (*setvco)(struct clk *, struct icst307_vco vco); |
22 | 20 | }; |
23 | - | |
24 | -int clk_register(struct clk *clk); | |
25 | -void clk_unregister(struct clk *clk); |
arch/arm/mach-versatile/core.c
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | #include <linux/cnt32_to_63.h> |
32 | 32 | #include <linux/io.h> |
33 | 33 | |
34 | +#include <asm/clkdev.h> | |
34 | 35 | #include <asm/system.h> |
35 | 36 | #include <mach/hardware.h> |
36 | 37 | #include <asm/irq.h> |
37 | 38 | |
38 | 39 | |
39 | 40 | |
40 | 41 | |
41 | 42 | |
... | ... | @@ -373,25 +374,63 @@ |
373 | 374 | |
374 | 375 | static 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_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET; | |
377 | + void __iomem *sys = __io_address(VERSATILE_SYS_BASE); | |
378 | + void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET; | |
378 | 379 | u32 val; |
379 | 380 | |
380 | - val = readl(sys_osc) & ~0x7ffff; | |
381 | + val = readl(sys + clk->oscoff) & ~0x7ffff; | |
381 | 382 | val |= vco.v | (vco.r << 9) | (vco.s << 16); |
382 | 383 | |
383 | 384 | writel(0xa05f, sys_lock); |
384 | - writel(val, sys_osc); | |
385 | + writel(val, sys + clk->oscoff); | |
385 | 386 | writel(0, sys_lock); |
386 | 387 | } |
387 | 388 | |
388 | -static struct clk versatile_clcd_clk = { | |
389 | - .name = "CLCDCLK", | |
389 | +static struct clk osc4_clk = { | |
390 | 390 | .params = &versatile_oscvco_params, |
391 | - .setvco = versatile_oscvco_set, | |
391 | + .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET, | |
392 | + .setvco = versatile_oscvco_set, | |
392 | 393 | }; |
393 | 394 | |
394 | 395 | /* |
396 | + * These are fixed clocks. | |
397 | + */ | |
398 | +static struct clk ref24_clk = { | |
399 | + .rate = 24000000, | |
400 | +}; | |
401 | + | |
402 | +static 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 | + } | |
431 | +}; | |
432 | + | |
433 | +/* | |
395 | 434 | * CLCD support. |
396 | 435 | */ |
397 | 436 | #define SYS_CLCD_MODE_MASK (3 << 0) |
... | ... | @@ -786,7 +825,8 @@ |
786 | 825 | { |
787 | 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 | 831 | platform_device_register(&versatile_flash_device); |
792 | 832 | platform_device_register(&versatile_i2c_device); |
arch/arm/mach-versatile/include/mach/clkdev.h