From patchwork Fri Jun 24 11:05:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benoit Cousson X-Patchwork-Id: 915862 X-Patchwork-Delegate: b-cousson@ti.com 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 p5OB6HgV010552 for ; Fri, 24 Jun 2011 11:06:38 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755219Ab1FXLGh (ORCPT ); Fri, 24 Jun 2011 07:06:37 -0400 Received: from comal.ext.ti.com ([198.47.26.152]:51901 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755134Ab1FXLGe (ORCPT ); Fri, 24 Jun 2011 07:06:34 -0400 Received: from dlep36.itg.ti.com ([157.170.170.91]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id p5OB6W5l012726 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 24 Jun 2011 06:06:32 -0500 Received: from dlep26.itg.ti.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id p5OB6Wi4006287; Fri, 24 Jun 2011 06:06:32 -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 p5OB6Wgg006235; Fri, 24 Jun 2011 06:06:32 -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, 24 Jun 2011 06:06:32 -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 p5OB62v2024325; Fri, 24 Jun 2011 06:06:30 -0500 From: Benoit Cousson To: CC: rnayak@ti.com, santosh.shilimkar@ti.com, linux-omap@vger.kernel.org, Benoit Cousson Subject: [PATCH 13/14] OMAP4: hwmod: Introduce the module control in hwmod control Date: Fri, 24 Jun 2011 13:05:59 +0200 Message-ID: <1308913560-333-14-git-send-email-b-cousson@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: References: 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, 24 Jun 2011 11:06:38 +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 5c0169c..6b144c4 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 * * @@ -1329,6 +1379,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 @@ -1381,11 +1432,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_warning("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) @@ -1477,11 +1535,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_warning("omap_hwmod: %s: _wait_target_disable failed\n", oh->name); + _disable_clocks(oh); } /* XXX Should this code also force-disable the optional clocks? */