Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
arm
mach-tegra
clock.c
Go to the documentation of this file.
1
/*
2
*
3
* Copyright (C) 2010 Google, Inc.
4
* Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved.
5
*
6
* Author:
7
* Colin Cross <
[email protected]
>
8
*
9
* This software is licensed under the terms of the GNU General Public
10
* License version 2, as published by the Free Software Foundation, and
11
* may be copied, distributed, and modified under those terms.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
*/
19
20
#include <linux/kernel.h>
21
#include <
linux/clk.h
>
22
#include <
linux/clkdev.h
>
23
#include <
linux/init.h
>
24
#include <linux/list.h>
25
#include <linux/module.h>
26
#include <linux/sched.h>
27
#include <
linux/seq_file.h
>
28
#include <linux/slab.h>
29
30
#include <mach/clk.h>
31
32
#include "
board.h
"
33
#include "
clock.h
"
34
#include "
tegra_cpu_car.h
"
35
36
/* Global data of Tegra CPU CAR ops */
37
struct
tegra_cpu_car_ops
*
tegra_cpu_car_ops
;
38
39
/*
40
* Locking:
41
*
42
* An additional mutex, clock_list_lock, is used to protect the list of all
43
* clocks.
44
*
45
*/
46
static
DEFINE_MUTEX
(clock_list_lock);
47
static
LIST_HEAD
(clocks);
48
49
void
tegra_clk_add
(
struct
clk
*
clk
)
50
{
51
struct
clk_tegra
*
c
=
to_clk_tegra
(
__clk_get_hw
(clk));
52
53
mutex_lock
(&clock_list_lock);
54
list_add(&c->
node
, &clocks);
55
mutex_unlock
(&clock_list_lock);
56
}
57
58
struct
clk
*
tegra_get_clock_by_name
(
const
char
*
name
)
59
{
60
struct
clk_tegra
*
c
;
61
struct
clk
*
ret
=
NULL
;
62
mutex_lock
(&clock_list_lock);
63
list_for_each_entry
(c, &clocks,
node
) {
64
if
(
strcmp
(
__clk_get_name
(c->
hw
.clk), name) == 0) {
65
ret = c->
hw
.clk;
66
break
;
67
}
68
}
69
mutex_unlock
(&clock_list_lock);
70
return
ret
;
71
}
72
73
static
int
tegra_clk_init_one_from_table(
struct
tegra_clk_init_table
*
table
)
74
{
75
struct
clk
*
c
;
76
struct
clk
*
p
;
77
struct
clk
*
parent
;
78
79
int
ret
= 0;
80
81
c =
tegra_get_clock_by_name
(table->
name
);
82
83
if
(!c) {
84
pr_warn
(
"Unable to initialize clock %s\n"
,
85
table->
name
);
86
return
-
ENODEV
;
87
}
88
89
parent =
clk_get_parent
(c);
90
91
if
(table->
parent
) {
92
p =
tegra_get_clock_by_name
(table->
parent
);
93
if
(!p) {
94
pr_warn
(
"Unable to find parent %s of clock %s\n"
,
95
table->
parent
, table->
name
);
96
return
-
ENODEV
;
97
}
98
99
if
(parent != p) {
100
ret =
clk_set_parent
(c, p);
101
if
(ret) {
102
pr_warn
(
"Unable to set parent %s of clock %s: %d\n"
,
103
table->
parent
, table->
name
, ret);
104
return
-
EINVAL
;
105
}
106
}
107
}
108
109
if
(table->
rate
&& table->
rate
!=
clk_get_rate
(c)) {
110
ret =
clk_set_rate
(c, table->
rate
);
111
if
(ret) {
112
pr_warn
(
"Unable to set clock %s to rate %lu: %d\n"
,
113
table->
name
, table->
rate
, ret);
114
return
-
EINVAL
;
115
}
116
}
117
118
if
(table->
enabled
) {
119
ret = clk_prepare_enable(c);
120
if
(ret) {
121
pr_warn
(
"Unable to enable clock %s: %d\n"
,
122
table->
name
, ret);
123
return
-
EINVAL
;
124
}
125
}
126
127
return
0;
128
}
129
130
void
tegra_clk_init_from_table
(
struct
tegra_clk_init_table
*table)
131
{
132
for
(; table->
name
; table++)
133
tegra_clk_init_one_from_table(table);
134
}
135
136
void
tegra_periph_reset_deassert
(
struct
clk
*c)
137
{
138
struct
clk_tegra
*
clk
=
to_clk_tegra
(
__clk_get_hw
(c));
139
BUG_ON
(!clk->
reset
);
140
clk->
reset
(
__clk_get_hw
(c),
false
);
141
}
142
EXPORT_SYMBOL
(
tegra_periph_reset_deassert
);
143
144
void
tegra_periph_reset_assert
(
struct
clk
*c)
145
{
146
struct
clk_tegra
*
clk
=
to_clk_tegra
(
__clk_get_hw
(c));
147
BUG_ON
(!clk->
reset
);
148
clk->
reset
(
__clk_get_hw
(c),
true
);
149
}
150
EXPORT_SYMBOL
(
tegra_periph_reset_assert
);
151
152
/* Several extended clock configuration bits (e.g., clock routing, clock
153
* phase control) are included in PLL and peripheral clock source
154
* registers. */
155
int
tegra_clk_cfg_ex
(
struct
clk
*c,
enum
tegra_clk_ex_param
p,
u32
setting)
156
{
157
int
ret = 0;
158
struct
clk_tegra
*
clk
=
to_clk_tegra
(
__clk_get_hw
(c));
159
160
if
(!clk->
clk_cfg_ex
) {
161
ret = -
ENOSYS
;
162
goto
out
;
163
}
164
ret = clk->
clk_cfg_ex
(
__clk_get_hw
(c), p, setting);
165
166
out
:
167
return
ret
;
168
}
Generated on Thu Jan 10 2013 12:56:38 for Linux Kernel by
1.8.2