Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 
  This page was automatically generated by the LXR engine.