Skip to content

Commit

Permalink
OMAP: PM counter infrastructure.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Peter 'p2' De Schrijver authored and metaliveblog committed Sep 2, 2009
1 parent 36d568e commit ba20bb1
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 2 deletions.
2 changes: 2 additions & 0 deletions arch/arm/mach-omap2/clockdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
v << __ffs(clkdm->clktrctrl_mask),
clkdm->pwrdm.ptr->prcm_offs,
CM_CLKSTCTRL);

pwrdm_clkdm_state_switch(clkdm);
}

/**
Expand Down
101 changes: 99 additions & 2 deletions arch/arm/mach-omap2/powerdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
#include <mach/powerdomain.h>
#include <mach/clockdomain.h>

enum {
PWRDM_STATE_NOW = 0,
PWRDM_STATE_PREV,
};

/* pwrdm_list contains all registered struct powerdomains */
static LIST_HEAD(pwrdm_list);

Expand Down Expand Up @@ -102,6 +107,63 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
return pd->pwrdm;
}

static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
{

int prev;
int state;

if (pwrdm == NULL)
return -EINVAL;

state = pwrdm_read_pwrst(pwrdm);

switch (flag) {
case PWRDM_STATE_NOW:
prev = pwrdm->state;
break;
case PWRDM_STATE_PREV:
prev = pwrdm_read_prev_pwrst(pwrdm);
if (pwrdm->state != prev)
pwrdm->state_counter[prev]++;
break;
default:
return -EINVAL;
}

if (state != prev)
pwrdm->state_counter[state]++;

pwrdm->state = state;

return 0;
}

static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm)
{
pwrdm_clear_all_prev_pwrst(pwrdm);
_pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
return 0;
}

static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm)
{
_pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
return 0;
}

static __init void _pwrdm_setup(struct powerdomain *pwrdm)
{
int i;

for (i = 0; i < 4; i++)
pwrdm->state_counter[i] = 0;

pwrdm_wait_transition(pwrdm);
pwrdm->state = pwrdm_read_pwrst(pwrdm);
pwrdm->state_counter[pwrdm->state] = 1;

}

/* Public functions */

Expand All @@ -117,9 +179,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
{
struct powerdomain **p = NULL;

if (pwrdm_list)
for (p = pwrdm_list; *p; p++)
if (pwrdm_list) {
for (p = pwrdm_list; *p; p++) {
pwrdm_register(*p);
_pwrdm_setup(*p);
}
}
}

/**
Expand Down Expand Up @@ -1110,4 +1175,36 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm)
return 0;
}

int pwrdm_state_switch(struct powerdomain *pwrdm)
{
return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
}

int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
{
if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
pwrdm_wait_transition(clkdm->pwrdm.ptr);
return pwrdm_state_switch(clkdm->pwrdm.ptr);
}

return -EINVAL;
}
int pwrdm_clk_state_switch(struct clk *clk)
{
if (clk != NULL && clk->clkdm != NULL)
return pwrdm_clkdm_state_switch(clk->clkdm);
return -EINVAL;
}

int pwrdm_pre_transition(void)
{
pwrdm_for_each(_pwrdm_pre_transition_cb);
return 0;
}

int pwrdm_post_transition(void)
{
pwrdm_for_each(_pwrdm_post_transition_cb);
return 0;
}

7 changes: 7 additions & 0 deletions arch/arm/plat-omap/include/mach/powerdomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ struct powerdomain {

struct list_head node;

int state;
unsigned state_counter[4];
};


Expand Down Expand Up @@ -164,4 +166,9 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);

int pwrdm_wait_transition(struct powerdomain *pwrdm);

int pwrdm_state_switch(struct powerdomain *pwrdm);
int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
int pwrdm_pre_transition(void);
int pwrdm_post_transition(void);

#endif

0 comments on commit ba20bb1

Please sign in to comment.