1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* linux/arch/arm/mach-sa1100/clock.c
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <asm/arch/pxa-regs.h>
#include <asm/hardware.h>
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
unsigned int enabled;
void (*enable)(void);
void (*disable)(void);
};
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
if (clk->enabled++ == 0)
clk->enable();
spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
WARN_ON(clk->enabled == 0);
spin_lock_irqsave(&clocks_lock, flags);
if (--clk->enabled == 0)
clk->disable();
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
static void clk_gpio27_enable(void)
{
pxa_gpio_mode(GPIO11_3_6MHz_MD);
}
static void clk_gpio27_disable(void)
{
}
static struct clk clk_gpio27 = {
.name = "GPIO27_CLK",
.rate = 3686400,
.enable = clk_gpio27_enable,
.disable = clk_gpio27_disable,
};
int clk_register(struct clk *clk)
{
mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
mutex_lock(&clocks_mutex);
list_del(&clk->node);
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
static int __init clk_init(void)
{
clk_register(&clk_gpio27);
return 0;
}
arch_initcall(clk_init);
|