From: Paul Walmsley <paul@pwsan.com>
To: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Cc: "Benoît Cousson" <b-cousson@ti.com>
Subject: [PATCH 7/7] ARM: OMAP2+: hwmod: split the _setup() function
Date: Mon, 30 Jan 2012 03:18:18 -0700 [thread overview]
Message-ID: <20120130101818.10450.56384.stgit@dusk> (raw)
In-Reply-To: <20120130101251.10450.58423.stgit@dusk>
Split the interface clock setup from _setup() into
_setup_iclk_autoidle() and split the post-setup state code from
_setup() into _enter_postsetup_state(). Fix the existing, incorrect
documentation for _setup(), and add documentation for the other two
functions. The goal is to shrink the size of the _setup() function to
make it easier to read and maintain.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
---
arch/arm/mach-omap2/omap_hwmod.c | 154 +++++++++++++++++++++++++++-----------
1 files changed, 111 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index f7bf759..41749bd 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1731,11 +1731,112 @@ static int _shutdown(struct omap_hwmod *oh)
}
/**
- * _setup - do initial configuration of omap_hwmod
+ * _setup_iclk_autoidle - configure an IP block's interface clocks
* @oh: struct omap_hwmod *
*
- * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register. Returns 0.
+ * Set up the module's interface clocks. XXX This function is still mostly
+ * a stub; implementing this properly requires iclk autoidle usecounting in
+ * the clock code. No return value.
+ */
+static void _setup_iclk_autoidle(struct omap_hwmod *oh)
+{
+ int i;
+
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+ struct clk *c = os->_clk;
+
+ if (!c)
+ continue;
+
+ if (os->flags & OCPIF_SWSUP_IDLE) {
+ /* XXX omap_iclk_deny_idle(c); */
+ } else {
+ /* XXX omap_iclk_allow_idle(c); */
+ clk_enable(c);
+ }
+ }
+}
+
+
+/**
+ * _enter_postsetup_state - transition to the appropriate state after _setup
+ * @oh: struct omap_hwmod *
+ *
+ * Place an IP block represented by @oh into a "post-setup" state --
+ * either IDLE, ENABLED, or DISABLED. ("post-setup" simply means that
+ * this function is called at the end of _setup().) The postsetup
+ * state for an IP block can be changed by calling
+ * omap_hwmod_enter_postsetup_state() early in the boot process,
+ * before one of the omap_hwmod_setup*() functions are called for the
+ * IP block.
+ *
+ * The IP block stays in this state until a PM runtime-based driver is
+ * loaded for that IP block. A post-setup state of IDLE is
+ * appropriate for almost all IP blocks with runtime PM-enabled
+ * drivers, since those drivers are able to enable the IP block. A
+ * post-setup state of ENABLED is appropriate for kernels with PM
+ * runtime disabled. The DISABLED state is appropriate for unusual IP
+ * blocks such as the MPU WDTIMER on kernels without WDTIMER drivers
+ * included, since the WDTIMER starts running on reset and will reset
+ * the MPU if left active.
+ *
+ * This post-setup mechanism is deprecated. Once all of the OMAP
+ * drivers have been converted to use PM runtime, and all of the IP
+ * block data and interconnect data is available to the hwmod code, it
+ * should be possible to replace this mechanism with a "lazy reset"
+ * arrangement. In a "lazy reset" setup, each IP block is enabled
+ * when the driver first probes, then all remaining IP blocks without
+ * drivers are either shut down or enabled after the drivers have
+ * loaded. However, this cannot take place until the above
+ * preconditions have been met, since otherwise the late reset code
+ * has no way of knowing which IP blocks are in use by drivers, and
+ * which ones are unused.
+ *
+ * No return value.
+ */
+static void _enter_postsetup_state(struct omap_hwmod *oh)
+{
+ u8 postsetup_state;
+
+ postsetup_state = oh->_postsetup_state;
+ if (postsetup_state == _HWMOD_STATE_UNKNOWN)
+ postsetup_state = _HWMOD_STATE_ENABLED;
+
+ /*
+ * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
+ * it should be set by the core code as a runtime flag during startup
+ */
+ if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
+ (postsetup_state == _HWMOD_STATE_IDLE)) {
+ oh->_int_flags |= _HWMOD_SKIP_ENABLE;
+ postsetup_state = _HWMOD_STATE_ENABLED;
+ }
+
+ if (postsetup_state == _HWMOD_STATE_IDLE)
+ _idle(oh);
+ else if (postsetup_state == _HWMOD_STATE_DISABLED)
+ _shutdown(oh);
+ else if (postsetup_state != _HWMOD_STATE_ENABLED)
+ WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
+ oh->name, postsetup_state);
+}
+
+/**
+ * _setup - do initial configuration of an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Configure the IP block represented by @oh. This may include
+ * enabling the IP block, resetting it, and placing it into a
+ * post-setup state, depending on the type of IP block and applicable
+ * flags.
+ *
+ * IP blocks are reset to prevent any previous configuration by the
+ * bootloader or previous operating system from interfering with power
+ * management or other parts of the system. The reset can be avoided; see
+ * omap_hwmod_no_setup_reset().
+ *
+ * Returns 0.
*/
static int _setup(struct omap_hwmod *oh, void *data)
{
@@ -1746,22 +1847,8 @@ static int _setup(struct omap_hwmod *oh, void *data)
return 0;
/* Set iclk autoidle mode */
- if (oh->slaves_cnt > 0) {
- for (i = 0; i < oh->slaves_cnt; i++) {
- struct omap_hwmod_ocp_if *os = oh->slaves[i];
- struct clk *c = os->_clk;
-
- if (!c)
- continue;
-
- if (os->flags & OCPIF_SWSUP_IDLE) {
- /* XXX omap_iclk_deny_idle(c); */
- } else {
- /* XXX omap_iclk_allow_idle(c); */
- clk_enable(c);
- }
- }
- }
+ if (oh->slaves_cnt > 0)
+ _setup_iclk_autoidle(oh);
oh->_state = _HWMOD_STATE_INITIALIZED;
@@ -1785,27 +1872,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
if (!(oh->flags & HWMOD_INIT_NO_RESET))
_reset(oh);
- postsetup_state = oh->_postsetup_state;
- if (postsetup_state == _HWMOD_STATE_UNKNOWN)
- postsetup_state = _HWMOD_STATE_ENABLED;
-
- /*
- * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
- * it should be set by the core code as a runtime flag during startup
- */
- if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
- (postsetup_state == _HWMOD_STATE_IDLE)) {
- oh->_int_flags |= _HWMOD_SKIP_ENABLE;
- postsetup_state = _HWMOD_STATE_ENABLED;
- }
-
- if (postsetup_state == _HWMOD_STATE_IDLE)
- _idle(oh);
- else if (postsetup_state == _HWMOD_STATE_DISABLED)
- _shutdown(oh);
- else if (postsetup_state != _HWMOD_STATE_ENABLED)
- WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
- oh->name, postsetup_state);
+ _enter_postsetup_state(oh);
return 0;
}
@@ -2660,9 +2727,10 @@ int omap_hwmod_for_each_by_class(const char *classname,
*
* Sets the hwmod state that @oh will enter at the end of _setup()
* (called by omap_hwmod_setup_*()). Only valid to call between
- * calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns
- * 0 upon success or -EINVAL if there is a problem with the arguments
- * or if the hwmod is in the wrong state.
+ * calling omap_hwmod_register() and omap_hwmod_setup_*(). See also
+ * the documentation for _enter_postsetup_state(), above. Returns 0
+ * upon success or -EINVAL if there is a problem with the arguments or
+ * if the hwmod is in the wrong state.
*/
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
{
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2012-01-30 10:18 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-30 10:18 [PATCH 0/7] ARM: OMAP2+: hwmod/timer: first set of cleanups for 3.4 Paul Walmsley
2012-01-30 10:18 ` [PATCH 1/7] ARM: OMAP2+: hwmod: control all hardreset lines attached to a hwmod Paul Walmsley
2012-01-30 10:18 ` [PATCH 2/7] ARM: OMAP4: hwmod data: remove pseudo-hwmods associated with hardreset lines Paul Walmsley
2012-01-30 10:18 ` [PATCH 3/7] ARM: OMAP2+: hwmod: ensure that SYSCONFIG bits are reprogrammed after a reset Paul Walmsley
2012-01-30 10:18 ` [PATCH 4/7] ARM: OMAP2+: hwmod: provide a function to return the address space of the MPU RT Paul Walmsley
2012-01-30 10:18 ` [PATCH 5/7] ARM: OMAP2+: hwmod: add omap_hwmod_get_mpu_irq() and omap_hwmod_get_mpu_rt_pa() Paul Walmsley
2012-01-30 17:13 ` Tony Lindgren
2012-01-30 21:36 ` Paul Walmsley
2012-01-30 10:18 ` Paul Walmsley [this message]
2012-01-30 10:18 ` [PATCH 6/7] ARM: OMAP2+: timer: use a proper interface to get hwmod data Paul Walmsley
2012-01-30 23:14 ` [PATCH 0/7] ARM: OMAP2+: hwmod/timer: first set of cleanups for 3.4 Kevin Hilman
2012-01-30 23:36 ` Paul Walmsley
2012-01-31 8:05 ` Cousson, Benoit
2012-01-31 8:14 ` Paul Walmsley
2012-01-31 8:19 ` Cousson, Benoit
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=20120130101818.10450.56384.stgit@dusk \
--to=paul@pwsan.com \
--cc=b-cousson@ti.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.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).