diff options
| -rw-r--r-- | arch/arm/Kconfig | 1 | ||||
| -rw-r--r-- | arch/arm/mach-versatile/clock.c | 80 | ||||
| -rw-r--r-- | arch/arm/mach-versatile/clock.h | 7 | ||||
| -rw-r--r-- | arch/arm/mach-versatile/core.c | 56 | ||||
| -rw-r--r-- | arch/arm/mach-versatile/include/mach/clkdev.h | 7 |
5 files changed, 62 insertions, 89 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f1ac3937365e..75f0319628ba 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -231,6 +231,7 @@ config ARCH_VERSATILE | |||
| 231 | select ARM_AMBA | 231 | select ARM_AMBA |
| 232 | select ARM_VIC | 232 | select ARM_VIC |
| 233 | select HAVE_CLK | 233 | select HAVE_CLK |
| 234 | select COMMON_CLKDEV | ||
| 234 | select ICST307 | 235 | select ICST307 |
| 235 | select GENERIC_TIME | 236 | select GENERIC_TIME |
| 236 | select GENERIC_CLOCKEVENTS | 237 | select GENERIC_CLOCKEVENTS |
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 | ||
| 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 | int clk_enable(struct clk *clk) | 26 | int clk_enable(struct clk *clk) |
| 51 | { | 27 | { |
| 52 | return 0; | 28 | return 0; |
| @@ -66,7 +42,9 @@ EXPORT_SYMBOL(clk_get_rate); | |||
| 66 | 42 | ||
| 67 | long clk_round_rate(struct clk *clk, unsigned long rate) | 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 | EXPORT_SYMBOL(clk_round_rate); | 49 | EXPORT_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 | } |
| 91 | EXPORT_SYMBOL(clk_set_rate); | 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); | ||
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; | |||
| 12 | struct icst307_params; | 12 | struct icst307_params; |
| 13 | 13 | ||
| 14 | struct clk { | 14 | struct 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 | |||
| 24 | int clk_register(struct clk *clk); | ||
| 25 | void 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 | ||
| 374 | static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco) | 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 = __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 | ||
| 388 | static struct clk versatile_clcd_clk = { | 389 | static 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 | */ | ||
| 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 | } | ||
| 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 | ||
