From patchwork Mon Jan 30 10:18:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 138539 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B209A1007D1 for ; Mon, 30 Jan 2012 21:23:21 +1100 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1RroLT-0002Pf-1m; Mon, 30 Jan 2012 10:20:20 +0000 Received: from utopia.booyaka.com ([72.9.107.138]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1RroJw-0001xc-Ns for linux-arm-kernel@lists.infradead.org; Mon, 30 Jan 2012 10:18:51 +0000 Received: (qmail 7715 invoked by uid 1019); 30 Jan 2012 10:18:44 -0000 MBOX-Line: From nobody Mon Jan 30 03:18:18 2012 Subject: [PATCH 7/7] ARM: OMAP2+: hwmod: split the _setup() function To: linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org From: Paul Walmsley Date: Mon, 30 Jan 2012 03:18:18 -0700 Message-ID: <20120130101818.10450.56384.stgit@dusk> In-Reply-To: <20120130101251.10450.58423.stgit@dusk> References: <20120130101251.10450.58423.stgit@dusk> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.0 DECEASED_NO_ML Dead not via mailing list Cc: =?utf-8?q?Beno=C3=AEt?= Cousson X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org 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 Cc: BenoƮt Cousson --- 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) {