1 /* 2 * linux/arch/arm/mach-sa1100/clock.c 3 */ 4 #include <linux/module.h> 5 #include <linux/kernel.h> 6 #include <linux/device.h> 7 #include <linux/list.h> 8 #include <linux/errno.h> 9 #include <linux/err.h> 10 #include <linux/string.h> 11 #include <linux/clk.h> 12 #include <linux/spinlock.h> 13 #include <linux/mutex.h> 14 15 #include <mach/hardware.h> 16 17 /* 18 * Very simple clock implementation - we only have one clock to deal with. 19 */ 20 struct clk { 21 unsigned int enabled; 22 }; 23 24 static void clk_gpio27_enable(void) 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 35 static void clk_gpio27_disable(void) 36 { 37 TUCR = 0; 38 GPDR &= ~GPIO_32_768kHz; 39 GAFR &= ~GPIO_32_768kHz; 40 } 41 42 static struct clk clk_gpio27; 43 44 static DEFINE_SPINLOCK(clocks_lock); 45 46 struct 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 } 52 EXPORT_SYMBOL(clk_get); 53 54 void clk_put(struct clk *clk) 55 { 56 } 57 EXPORT_SYMBOL(clk_put); 58 59 int clk_enable(struct clk *clk) 60 { 61 unsigned long flags; 62 63 spin_lock_irqsave(&clocks_lock, flags); 64 if (clk->enabled++ == 0) 65 clk_gpio27_enable(); 66 spin_unlock_irqrestore(&clocks_lock, flags); 67 return 0; 68 } 69 EXPORT_SYMBOL(clk_enable); 70 71 void clk_disable(struct clk *clk) 72 { 73 unsigned long flags; 74 75 WARN_ON(clk->enabled == 0); 76 77 spin_lock_irqsave(&clocks_lock, flags); 78 if (--clk->enabled == 0) 79 clk_gpio27_disable(); 80 spin_unlock_irqrestore(&clocks_lock, flags); 81 } 82 EXPORT_SYMBOL(clk_disable); 83 84 unsigned long clk_get_rate(struct clk *clk) 85 { 86 return 3686400; 87 } 88 EXPORT_SYMBOL(clk_get_rate); 89