From: paul@pwsan.com (Paul Walmsley)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 03/12] ARM: OMAP2+: powerdomain: split pwrdm_state_switch()
Date: Sun, 09 Dec 2012 13:03:21 -0700 [thread overview]
Message-ID: <20121209200317.3196.54821.stgit@dusk.lan> (raw)
In-Reply-To: <20121209200108.3196.12452.stgit@dusk.lan>
Move the pwrdm_state_switch() code that deals with previous power
states into the post-transition callback. This improves the clarity
of pwrdm_state_switch() considerably. Add some sorely-needed
kerneldoc for these functions.
It should be possible to drop pwrdm_state_switch() completely during
3.9.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <t-kristo@ti.com>
---
arch/arm/mach-omap2/powerdomain.c | 118 ++++++++++++++++++++++++-------------
arch/arm/mach-omap2/powerdomain.h | 1
2 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 53bc852..d38f493 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -40,11 +40,6 @@
#define PWRDM_TRACE_STATES_FLAG (1<<31)
-enum {
- PWRDM_STATE_NOW = 0,
- PWRDM_STATE_PREV,
-};
-
/* Types of sleep_switch used in pwrdm_set_fpwrst() */
#define ALREADYACTIVE_SWITCH 0
#define FORCEWAKEUP_SWITCH 1
@@ -600,60 +595,97 @@ static void _pwrdm_update_pwrst_time(struct powerdomain *pwrdm, int prev)
#endif
}
-/* XXX Caller must hold pwrdm->_lock */
-static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
+/**
+ * _pwrdm_state_switch - record powerdomain usage data; track power state
+ * (before powerdomain state transition)
+ * @pwrdm: struct powerdomain * to observe
+ *
+ * If the powerdomain @pwrdm's current power state is not what we last
+ * observed it to be, then increment the counter for that power state.
+ * This is used to track context loss events, and for debugging. Also
+ * if CONFIG_PM_DEBUG=y, track the amount of time the powerdomain has
+ * spent in the current power state. Caller must hold pwrdm->_lock.
+ * Intended to be called immediately before the powerdomain's power
+ * state is likely to change. XXX Note that the counts and durations
+ * observed by this function may be inaccurate. Powerdomains can
+ * transition power states automatically, without the kernel being
+ * involved -- for example, a device can DMA data from memory while
+ * the MPU is asleep. This function does not attempt to account for
+ * that. XXX It may be possible to skip this function completely if
+ * PM debugging is not needed and off-mode and OSWR is disabled (e.g.,
+ * no context loss events). No return value.
+ */
+static void _pwrdm_state_switch(struct powerdomain *pwrdm)
{
- int prev, next, fpwrst, trace_state = 0;
-
- if (pwrdm == NULL)
- return -EINVAL;
+ int fpwrst;
fpwrst = _pwrdm_read_fpwrst(pwrdm);
-
- switch (flag) {
- case PWRDM_STATE_NOW:
- prev = pwrdm->fpwrst;
- break;
- case PWRDM_STATE_PREV:
- prev = _pwrdm_read_prev_fpwrst(pwrdm);
- if (pwrdm->fpwrst != prev)
- pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
- /*
- * If the power domain did not hit the desired state,
- * generate a trace event with both the desired and hit states
- */
- next = _pwrdm_read_next_fpwrst(pwrdm);
- if (next != prev) {
- trace_state = (PWRDM_TRACE_STATES_FLAG | next << 8 |
- prev);
- trace_power_domain_target(pwrdm->name, trace_state,
- smp_processor_id());
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (fpwrst != prev)
+ if (fpwrst != pwrdm->fpwrst)
pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
- _pwrdm_update_pwrst_time(pwrdm, prev);
+ _pwrdm_update_pwrst_time(pwrdm, pwrdm->fpwrst);
pwrdm->fpwrst = fpwrst;
-
- return 0;
}
static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
{
pwrdm_clear_all_prev_pwrst(pwrdm);
- _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+ _pwrdm_state_switch(pwrdm);
return 0;
}
+/**
+ * _pwrdm_post_transition_cb - record powerdomain usage data; track power state
+ * (after powerdomain power state transition)
+ * @pwrdm: struct powerdomain * to observe
+ *
+ * If the powerdomain @pwrdm's previous power state doesn't match our
+ * recollection of the powerdomain's current power state, then
+ * increment the counter for the previous power state. And if the
+ * powerdomain's previous power state doesn't match the current power
+ * state, increment the counter for the current power state. This
+ * function is used to track context loss events, and for debugging.
+ * Also if CONFIG_PM_DEBUG=y, track the approximate amount of time the
+ * powerdomain has spent in the previous power state. Caller must
+ * hold pwrdm->_lock. XXX Note that the counts and durations observed
+ * by this function may be inaccurate. Powerdomains can transition
+ * power states automatically, without the kernel being involved --
+ * for example, a device can DMA data from memory while the MPU is
+ * asleep. This function does not attempt to account for that. XXX
+ * It may be possible to skip this function completely if PM debugging
+ * is not needed and off-mode and OSWR is disabled (e.g., no context
+ * loss events). No return value.
+ */
static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
{
- _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
+ int prev, next, fpwrst;
+ int trace_state = 0;
+
+ prev = _pwrdm_read_prev_fpwrst(pwrdm);
+ if (pwrdm->fpwrst != prev)
+ pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
+
+ _pwrdm_update_pwrst_time(pwrdm, prev);
+
+ /*
+ * If the power domain did not hit the desired state,
+ * generate a trace event with both the desired and hit states
+ */
+ next = _pwrdm_read_next_fpwrst(pwrdm);
+ if (next != prev) {
+ trace_state = (PWRDM_TRACE_STATES_FLAG | next << 8 |
+ prev);
+ trace_power_domain_target(pwrdm->name, trace_state,
+ smp_processor_id());
+ }
+
+ fpwrst = _pwrdm_read_fpwrst(pwrdm);
+ if (fpwrst != prev)
+ pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
+
+ pwrdm->fpwrst = fpwrst;
+
return 0;
}
@@ -1055,7 +1087,7 @@ int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
if (!ret)
- ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+ _pwrdm_state_switch(pwrdm);
return ret;
}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 48bb325..ef51987b 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -237,6 +237,7 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);
int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);
int pwrdm_pre_transition(struct powerdomain *pwrdm);
int pwrdm_post_transition(struct powerdomain *pwrdm);
int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
next prev parent reply other threads:[~2012-12-09 20:03 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
2012-12-09 20:02 ` [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code Paul Walmsley
2012-12-09 20:03 ` [PATCH 02/12] ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code Paul Walmsley
2012-12-09 20:03 ` Paul Walmsley [this message]
2012-12-09 20:03 ` [PATCH 04/12] ARM: OMAP2+: PM: clean up some debugfs functions Paul Walmsley
2012-12-09 20:03 ` [PATCH 06/12] ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state Paul Walmsley
2012-12-09 20:03 ` [PATCH 07/12] ARM: OMAP2+: powerdomain: cache the powerdomain next power state Paul Walmsley
2012-12-09 20:03 ` [PATCH 08/12] ARM: OMAP2+: powerdomain: cache the powerdomain's previous " Paul Walmsley
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
2012-12-12 10:22 ` Vaibhav Hiremath
2012-12-19 21:09 ` Jon Hunter
2012-12-20 17:22 ` Paul Walmsley
2012-12-21 6:33 ` Santosh Shilimkar
2012-12-26 6:21 ` Bedia, Vaibhav
2012-12-26 6:31 ` Bedia, Vaibhav
2012-12-26 20:49 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 10/12] ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON Paul Walmsley
2012-12-09 20:03 ` [PATCH 11/12] ARM: OMAP2xxx: powerdomain: add previous power state tracking Paul Walmsley
2012-12-09 20:03 ` [PATCH 12/12] ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code Paul Walmsley
2013-01-04 14:26 ` [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Tero Kristo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121209200317.3196.54821.stgit@dusk.lan \
--to=paul@pwsan.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).