diff options
author | Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | 2008-10-15 10:48:43 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-09-02 18:08:23 -0400 |
commit | ba20bb126940ce4847e146a0d00b7f7b0868d773 (patch) | |
tree | d9a8f3c316aa66261ba026e9bd2507fa4ec9a931 /arch/arm/mach-omap2/powerdomain.c | |
parent | 36d568ec055cb3ac4507d38ebabba955cdbb443e (diff) |
OMAP: PM counter infrastructure.
This patch provides the infrastructure to count how many times a
powerdomain entered a given power state (on, inactive, retention,
off). A number of functions are provided which will be called by the
chip specific powerdomain and clockdomain code whenever a transition
might have happened.
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2/powerdomain.c')
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 101 |
1 files changed, 99 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 983f1cb676be..a2d98718c6d7 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <mach/powerdomain.h> | 35 | #include <mach/powerdomain.h> |
36 | #include <mach/clockdomain.h> | 36 | #include <mach/clockdomain.h> |
37 | 37 | ||
38 | enum { | ||
39 | PWRDM_STATE_NOW = 0, | ||
40 | PWRDM_STATE_PREV, | ||
41 | }; | ||
42 | |||
38 | /* pwrdm_list contains all registered struct powerdomains */ | 43 | /* pwrdm_list contains all registered struct powerdomains */ |
39 | static LIST_HEAD(pwrdm_list); | 44 | static LIST_HEAD(pwrdm_list); |
40 | 45 | ||
@@ -102,6 +107,63 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, | |||
102 | return pd->pwrdm; | 107 | return pd->pwrdm; |
103 | } | 108 | } |
104 | 109 | ||
110 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | ||
111 | { | ||
112 | |||
113 | int prev; | ||
114 | int state; | ||
115 | |||
116 | if (pwrdm == NULL) | ||
117 | return -EINVAL; | ||
118 | |||
119 | state = pwrdm_read_pwrst(pwrdm); | ||
120 | |||
121 | switch (flag) { | ||
122 | case PWRDM_STATE_NOW: | ||
123 | prev = pwrdm->state; | ||
124 | break; | ||
125 | case PWRDM_STATE_PREV: | ||
126 | prev = pwrdm_read_prev_pwrst(pwrdm); | ||
127 | if (pwrdm->state != prev) | ||
128 | pwrdm->state_counter[prev]++; | ||
129 | break; | ||
130 | default: | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | if (state != prev) | ||
135 | pwrdm->state_counter[state]++; | ||
136 | |||
137 | pwrdm->state = state; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm) | ||
143 | { | ||
144 | pwrdm_clear_all_prev_pwrst(pwrdm); | ||
145 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm) | ||
150 | { | ||
151 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static __init void _pwrdm_setup(struct powerdomain *pwrdm) | ||
156 | { | ||
157 | int i; | ||
158 | |||
159 | for (i = 0; i < 4; i++) | ||
160 | pwrdm->state_counter[i] = 0; | ||
161 | |||
162 | pwrdm_wait_transition(pwrdm); | ||
163 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | ||
164 | pwrdm->state_counter[pwrdm->state] = 1; | ||
165 | |||
166 | } | ||
105 | 167 | ||
106 | /* Public functions */ | 168 | /* Public functions */ |
107 | 169 | ||
@@ -117,9 +179,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list) | |||
117 | { | 179 | { |
118 | struct powerdomain **p = NULL; | 180 | struct powerdomain **p = NULL; |
119 | 181 | ||
120 | if (pwrdm_list) | 182 | if (pwrdm_list) { |
121 | for (p = pwrdm_list; *p; p++) | 183 | for (p = pwrdm_list; *p; p++) { |
122 | pwrdm_register(*p); | 184 | pwrdm_register(*p); |
185 | _pwrdm_setup(*p); | ||
186 | } | ||
187 | } | ||
123 | } | 188 | } |
124 | 189 | ||
125 | /** | 190 | /** |
@@ -1110,4 +1175,36 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) | |||
1110 | return 0; | 1175 | return 0; |
1111 | } | 1176 | } |
1112 | 1177 | ||
1178 | int pwrdm_state_switch(struct powerdomain *pwrdm) | ||
1179 | { | ||
1180 | return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
1181 | } | ||
1182 | |||
1183 | int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) | ||
1184 | { | ||
1185 | if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { | ||
1186 | pwrdm_wait_transition(clkdm->pwrdm.ptr); | ||
1187 | return pwrdm_state_switch(clkdm->pwrdm.ptr); | ||
1188 | } | ||
1189 | |||
1190 | return -EINVAL; | ||
1191 | } | ||
1192 | int pwrdm_clk_state_switch(struct clk *clk) | ||
1193 | { | ||
1194 | if (clk != NULL && clk->clkdm != NULL) | ||
1195 | return pwrdm_clkdm_state_switch(clk->clkdm); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1198 | |||
1199 | int pwrdm_pre_transition(void) | ||
1200 | { | ||
1201 | pwrdm_for_each(_pwrdm_pre_transition_cb); | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | int pwrdm_post_transition(void) | ||
1206 | { | ||
1207 | pwrdm_for_each(_pwrdm_post_transition_cb); | ||
1208 | return 0; | ||
1209 | } | ||
1113 | 1210 | ||