From patchwork Fri Jul 1 21:09:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Cousson X-Patchwork-Id: 938792 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p61LTcRZ014702 for ; Fri, 1 Jul 2011 21:49:46 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757034Ab1GAVJ5 (ORCPT ); Fri, 1 Jul 2011 17:09:57 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:41593 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756854Ab1GAVJx (ORCPT ); Fri, 1 Jul 2011 17:09:53 -0400 Received: from dlep33.itg.ti.com ([157.170.170.112]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id p61L9jB1018717 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 1 Jul 2011 16:09:45 -0500 Received: from dlep26.itg.ti.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep33.itg.ti.com (8.13.7/8.13.8) with ESMTP id p61L9ibl024981; Fri, 1 Jul 2011 16:09:44 -0500 (CDT) Received: from dlee74.ent.ti.com (localhost [127.0.0.1]) by dlep26.itg.ti.com (8.13.8/8.13.8) with ESMTP id p61L9iGa013025; Fri, 1 Jul 2011 16:09:44 -0500 (CDT) Received: from dlelxv22.itg.ti.com (172.17.1.197) by dlee74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 8.3.106.1; Fri, 1 Jul 2011 16:09:44 -0500 Received: from localhost.localdomain (lncpu04.tif.ti.com [137.167.102.15]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id p61L9ORS016360; Fri, 1 Jul 2011 16:09:43 -0500 From: Benoit Cousson To: CC: rnayak@ti.com, linux-omap@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Benoit Cousson Subject: [PATCH v3 13/13] OMAP4: hwmod: Introduce the module control in hwmod control Date: Fri, 1 Jul 2011 23:09:18 +0200 Message-ID: <1309554558-19819-14-git-send-email-b-cousson@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1309554558-19819-1-git-send-email-b-cousson@ti.com> References: <1309554558-19819-1-git-send-email-b-cousson@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 01 Jul 2011 21:49:47 +0000 (UTC) Take advantage of the explicit modulemode control to fix the way parents clocks are managed. A module must be disabled before any parents are disabled. That programming model was not possible with the previous implementation that was considering a modulemode as a leaf clock node managed by the clock fmwk. This was leading to bad crash upon disable when the parent clock was gated before the module completed its transition to idle. Signed-off-by: Benoit Cousson Cc: Paul Walmsley Cc: Rajendra Nayak --- arch/arm/mach-omap2/omap_hwmod.c | 63 ++++++++++++++++++++++++++++++++++++- 1 files changed, 61 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index ebca866..117a4d5 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -675,6 +675,56 @@ static void _disable_optional_clocks(struct omap_hwmod *oh) } /** + * _enable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Enables the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _enable_module(struct omap_hwmod *oh) +{ + /* The module mode does not exist prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: _enable_module: %d\n", + oh->name, oh->prcm.omap4.modulemode); + + omap4_cm_module_enable(oh->prcm.omap4.modulemode, + oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** + * _disable_module - enable CLKCTRL modulemode on OMAP4 + * @oh: struct omap_hwmod * + * + * Disable the PRCM module mode related to the hwmod @oh. + * No return value. + */ +static void _disable_module(struct omap_hwmod *oh) +{ + /* The module mode does not exist prior OMAP4 */ + if (cpu_is_omap24xx() || cpu_is_omap34xx()) + return; + + if (!oh->clkdm || !oh->prcm.omap4.modulemode) + return; + + pr_debug("omap_hwmod: %s: _disable_module\n", oh->name); + + omap4_cm_module_disable(oh->clkdm->prcm_partition, + oh->clkdm->cm_inst, + oh->clkdm->clkdm_offs, + oh->prcm.omap4.clkctrl_offs); +} + +/** * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use * @oh: struct omap_hwmod * * @@ -1331,6 +1381,7 @@ static int _enable(struct omap_hwmod *oh) _add_initiator_dep(oh, mpu_oh); _enable_clocks(oh); + _enable_module(oh); /* * If an IP contains only one HW reset line, then de-assert it in order @@ -1385,11 +1436,18 @@ static int _idle(struct omap_hwmod *oh) if (oh->class->sysc) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); - _disable_clocks(oh); + _disable_module(oh); ret = _wait_target_disable(oh); if (ret) pr_debug("omap_hwmod: %s: _wait_target_disable failed\n", oh->name); + /* + * The module must be in idle mode before disabling any parents + * clocks. Otherwise, the parent clock might be disabled before + * the module transition is done, and thus will prevent the + * transition to complete properly. + */ + _disable_clocks(oh); /* Mux pins for device idle if populated */ if (oh->mux && oh->mux->pads_dynamic) @@ -1481,11 +1539,12 @@ static int _shutdown(struct omap_hwmod *oh) if (oh->_state == _HWMOD_STATE_ENABLED) { _del_initiator_dep(oh, mpu_oh); /* XXX what about the other system initiators here? dma, dsp */ - _disable_clocks(oh); + _disable_module(oh); ret = _wait_target_disable(oh); if (ret) pr_debug("omap_hwmod: %s: _wait_target_disable failed\n", oh->name); + _disable_clocks(oh); } /* XXX Should this code also force-disable the optional clocks? */