From patchwork Thu Aug 13 16:52:30 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hilman X-Patchwork-Id: 41085 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7DGqkWJ009081 for ; Thu, 13 Aug 2009 16:52:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754881AbZHMQwn (ORCPT ); Thu, 13 Aug 2009 12:52:43 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754928AbZHMQwn (ORCPT ); Thu, 13 Aug 2009 12:52:43 -0400 Received: from wf-out-1314.google.com ([209.85.200.169]:49955 "EHLO wf-out-1314.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754881AbZHMQwm (ORCPT ); Thu, 13 Aug 2009 12:52:42 -0400 Received: by wf-out-1314.google.com with SMTP id 26so282476wfd.4 for ; Thu, 13 Aug 2009 09:52:43 -0700 (PDT) Received: by 10.142.3.31 with SMTP id 31mr193988wfc.142.1250182363792; Thu, 13 Aug 2009 09:52:43 -0700 (PDT) Received: from localhost ([216.254.16.51]) by mx.google.com with ESMTPS id 28sm1905185wfd.4.2009.08.13.09.52.42 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 13 Aug 2009 09:52:43 -0700 (PDT) From: Kevin Hilman To: linux-arm-kernel@lists.arm.linux.org.uk, linux-arm@vger.kernel.org Cc: linux-omap@vger.kernel.org, "Peter 'p2' De Schrijver" Subject: [PATCH 01/10] OMAP: PM counter infrastructure. Date: Thu, 13 Aug 2009 09:52:30 -0700 Message-Id: <1250182359-18830-2-git-send-email-khilman@deeprootsystems.com> X-Mailer: git-send-email 1.6.4 In-Reply-To: <1250182359-18830-1-git-send-email-khilman@deeprootsystems.com> References: <1250182359-18830-1-git-send-email-khilman@deeprootsystems.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org From: Peter 'p2' De Schrijver 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 Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/clockdomain.c | 2 + arch/arm/mach-omap2/powerdomain.c | 101 ++++++++++++++++++++++++- arch/arm/plat-omap/include/mach/powerdomain.h | 7 ++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 0e7d501..26912a9 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) v << __ffs(clkdm->clktrctrl_mask), clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL); + + pwrdm_clkdm_state_switch(clkdm); } /** diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 983f1cb..a2d9871 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -35,6 +35,11 @@ #include #include +enum { + PWRDM_STATE_NOW = 0, + PWRDM_STATE_PREV, +}; + /* pwrdm_list contains all registered struct powerdomains */ static LIST_HEAD(pwrdm_list); @@ -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 */ @@ -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); + } + } } /** @@ -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; +} diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h index 69c9e67..52663fc 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 { struct list_head node; + int state; + unsigned state_counter[4]; }; @@ -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