1 /* 2 * linux/arch/arm/mach-sa1100/clock.c 3 */ 4 #include <linux/module.h> 5 #include <linux/kernel.h> 6 #include <linux/list.h> 7 #include <linux/errno.h> 8 #include <linux/err.h> 9 #include <linux/string.h> 10 #include <linux/clk.h> 11 #include <linux/spinlock.h> 12 #include <linux/mutex.h> 13 14 #include <asm/hardware.h> 15 16 /* 17 * Very simple clock implementation - we only have one clock to 18 * deal with at the moment, so we only match using the "name". 19 */ 20 struct clk { 21 struct list_head node; 22 unsigned long rate; 23 const char *name; 24 unsigned int enabled; 25 void (*enable)(void); 26 void (*disable)(void); 27 }; 28 29 static LIST_HEAD(clocks); 30 static DEFINE_MUTEX(clocks_mutex); 31 static DEFINE_SPINLOCK(clocks_lock); 32 33 struct clk *clk_get(struct device *dev, const char *id) 34 { 35 struct clk *p, *clk = ERR_PTR(-ENOENT); 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 46 return clk; 47 } 48 EXPORT_SYMBOL(clk_get); 49 50 void clk_put(struct clk *clk) 51 { 52 } 53 EXPORT_SYMBOL(clk_put); 54 55 int clk_enable(struct clk *clk) 56 { 57 unsigned long flags; 58 59 spin_lock_irqsave(&clocks_lock, flags); 60 if (clk->enabled++ == 0) 61 clk->enable(); 62 spin_unlock_irqrestore(&clocks_lock, flags); 63 return 0; 64 } 65 EXPORT_SYMBOL(clk_enable); 66 67 void clk_disable(struct clk *clk) 68 { 69 unsigned long flags; 70 71 WARN_ON(clk->enabled == 0); 72 73 spin_lock_irqsave(&clocks_lock, flags); 74 if (--clk->enabled == 0) 75 clk->disable(); 76 spin_unlock_irqrestore(&clocks_lock, flags); 77 } 78 EXPORT_SYMBOL(clk_disable); 79 80 unsigned long clk_get_rate(struct clk *clk) 81 { 82 return clk->rate; 83 } 84 EXPORT_SYMBOL(clk_get_rate); 85 86 87 static 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 98 static void clk_gpio27_disable(void) 99 { 100 TUCR = 0; 101 GPDR &= ~GPIO_32_768kHz; 102 GAFR &= ~GPIO_32_768kHz; 103 } 104 105 static struct clk clk_gpio27 = { 106 .name = "GPIO27_CLK", 107 .rate = 3686400, 108 .enable = clk_gpio27_enable, 109 .disable = clk_gpio27_disable, 110 }; 111 112 int 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 } 119 EXPORT_SYMBOL(clk_register); 120 121 void clk_unregister(struct clk *clk) 122 { 123 mutex_lock(&clocks_mutex); 124 list_del(&clk->node); 125 mutex_unlock(&clocks_mutex); 126 } 127 EXPORT_SYMBOL(clk_unregister); 128 129 static int __init clk_init(void) 130 { 131 clk_register(&clk_gpio27); 132 return 0; 133 } 134 arch_initcall(clk_init); 135