aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter 'p2' De Schrijver <peter.de-schrijver@nokia.com>2008-10-15 10:48:43 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-09-02 18:08:23 -0400
commitba20bb126940ce4847e146a0d00b7f7b0868d773 (patch)
treed9a8f3c316aa66261ba026e9bd2507fa4ec9a931
parent36d568ec055cb3ac4507d38ebabba955cdbb443e (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>
-rw-r--r--arch/arm/mach-omap2/clockdomain.c2
-rw-r--r--arch/arm/mach-omap2/powerdomain.c101
-rw-r--r--arch/arm/plat-omap/include/mach/powerdomain.h7
3 files changed, 108 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 0e7d501865b6..26912a95dc18 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -484,6 +484,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
484 v << __ffs(clkdm->clktrctrl_mask), 484 v << __ffs(clkdm->clktrctrl_mask),
485 clkdm->pwrdm.ptr->prcm_offs, 485 clkdm->pwrdm.ptr->prcm_offs,
486 CM_CLKSTCTRL); 486 CM_CLKSTCTRL);
487
488 pwrdm_clkdm_state_switch(clkdm);
487} 489}
488 490
489/** 491/**
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
38enum {
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 */
39static LIST_HEAD(pwrdm_list); 44static 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
110static 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
142static 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
149static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm)
150{
151 _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
152 return 0;
153}
154
155static __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
1178int pwrdm_state_switch(struct powerdomain *pwrdm)
1179{
1180 return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
1181}
1182
1183int 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}
1192int 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
1199int pwrdm_pre_transition(void)
1200{
1201 pwrdm_for_each(_pwrdm_pre_transition_cb);
1202 return 0;
1203}
1204
1205int pwrdm_post_transition(void)
1206{
1207 pwrdm_for_each(_pwrdm_post_transition_cb);
1208 return 0;
1209}
1113 1210
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index 69c9e675d8ee..52663fc549d2 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -117,6 +117,8 @@ struct powerdomain {
117 117
118 struct list_head node; 118 struct list_head node;
119 119
120 int state;
121 unsigned state_counter[4];
120}; 122};
121 123
122 124
@@ -164,4 +166,9 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
164 166
165int pwrdm_wait_transition(struct powerdomain *pwrdm); 167int pwrdm_wait_transition(struct powerdomain *pwrdm);
166 168
169int pwrdm_state_switch(struct powerdomain *pwrdm);
170int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
171int pwrdm_pre_transition(void);
172int pwrdm_post_transition(void);
173
167#endif 174#endif