All of lore.kernel.org
 help / color / mirror / Atom feed
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

WARNING: multiple messages have this Message-ID (diff)
From: paul@pwsan.com (Paul Walmsley)
To: linux-arm-kernel@lists.infradead.org
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)
 {

  parent reply	other threads:[~2012-01-30 10:18 UTC|newest]

Thread overview: 30+ 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 ` 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   ` 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   ` 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   ` 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   ` 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 10:18   ` Paul Walmsley
2012-01-30 17:13   ` Tony Lindgren
2012-01-30 17:13     ` Tony Lindgren
2012-01-30 21:36     ` Paul Walmsley
2012-01-30 21:36       ` Paul Walmsley
2012-01-30 10:18 ` [PATCH 6/7] ARM: OMAP2+: timer: use a proper interface to get hwmod data Paul Walmsley
2012-01-30 10:18   ` Paul Walmsley
2012-01-30 10:18 ` Paul Walmsley [this message]
2012-01-30 10:18   ` [PATCH 7/7] ARM: OMAP2+: hwmod: split the _setup() function 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:14   ` Kevin Hilman
2012-01-30 23:36   ` Paul Walmsley
2012-01-30 23:36     ` Paul Walmsley
2012-01-31  8:05   ` Cousson, Benoit
2012-01-31  8:05     ` Cousson, Benoit
2012-01-31  8:14     ` Paul Walmsley
2012-01-31  8:14       ` Paul Walmsley
2012-01-31  8:19       ` Cousson, Benoit
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.