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 */ 20struct clk { 21 unsigned int enabled; 22}; 23 24static 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 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 44static DEFINE_SPINLOCK(clocks_lock); 45 46struct 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} 52EXPORT_SYMBOL(clk_get); 53 54void clk_put(struct clk *clk) 55{ 56} 57EXPORT_SYMBOL(clk_put); 58 59int 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} 69EXPORT_SYMBOL(clk_enable); 70 71void 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} 82EXPORT_SYMBOL(clk_disable); 83 84unsigned long clk_get_rate(struct clk *clk) 85{ 86 return 3686400; 87} 88EXPORT_SYMBOL(clk_get_rate); 89