From patchwork Tue Oct 5 06:01:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 231151 X-Patchwork-Delegate: paul@pwsan.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9561n65009066 for ; Tue, 5 Oct 2010 06:01:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757499Ab0JEGBd (ORCPT ); Tue, 5 Oct 2010 02:01:33 -0400 Received: from utopia.booyaka.com ([72.9.107.138]:37600 "EHLO utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757483Ab0JEGBd (ORCPT ); Tue, 5 Oct 2010 02:01:33 -0400 Received: (qmail 20826 invoked by uid 1019); 5 Oct 2010 06:01:32 -0000 Date: Tue, 5 Oct 2010 00:01:32 -0600 (MDT) From: Paul Walmsley To: "Cousson, Benoit" cc: "Nayak, Rajendra" , Kevin Hilman , Tony Lindgren , "linux-omap@vger.kernel.org" , "Varadarajan, Charulatha" , "Raja, Govindraj" Subject: Re: [GIT PULL] for testing: OMAP hwmod driver conversions: watchdog, UART, i2c In-Reply-To: <4CA60F88.4020303@ti.com> Message-ID: References: <8762xpenf8.fsf@deeprootsystems.com> <20100928201844.GI3117@atomide.com> <87tyl8rxwp.fsf@deeprootsystems.com> <20100930021819.GD3117@atomide.com> <877hi3i9cp.fsf@deeprootsystems.com> <87pqvvgt8g.fsf@deeprootsystems.com> <877hi3gqq7.fsf@deeprootsystems.com> <0680EC522D0CC943BC586913CF3768C003FF2DAF74@dbde02.ent.ti.com> <4CA60F88.4020303@ti.com> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) 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.3 (demeter1.kernel.org [140.211.167.41]); Tue, 05 Oct 2010 06:01:50 +0000 (UTC) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 955861a..fbcfe14 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1204,6 +1204,9 @@ int _omap_hwmod_enable(struct omap_hwmod *oh) r = _wait_target_ready(oh); if (!r) { + if (oh->enable_delay) + udelay(oh->enable_delay); + oh->_state = _HWMOD_STATE_ENABLED; /* Access the sysconfig only if the target is ready */ diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index c1835af..5a1e058 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -434,6 +434,7 @@ struct omap_hwmod_class { * @main_clk: main clock: OMAP clock name * @_clk: pointer to the main struct clk (filled in at runtime) * @opt_clks: other device clocks that drivers can request (0..*) + * @enable_delay: number of microseconds to wait after IdleReq is deasserted * @masters: ptr to array of OCP ifs that this hwmod can initiate on * @slaves: ptr to array of OCP ifs that this hwmod can respond on * @dev_attr: arbitrary device attributes that can be passed to the driver @@ -460,8 +461,35 @@ struct omap_hwmod_class { * accesses to complete." Modules may not have a main clock if the * interface clock also serves as a main clock. * - * Parameter names beginning with an underscore are managed internally by - * the omap_hwmod code and should not be set during initialization. + * On OMAP SoCs prior to OMAP4, some hwmods may require a non-zero + * @enable_delay value. A hwmod needs a non-zero @enable_delay if an + * imprecise external abort occurs while the hwmod is being enabled. + * This can happen if the hwmod takes a significant time to become + * ready for OCP transactions after the PRCM deasserts IdleAck to the + * module. @enable_delay specifies the number of microseconds for the + * hwmod code to udelay() between the time that the PRCM deasserts the + * IdleAck, and the time when the module is ready to handle register + * reads/writes. Most hwmods shouldn't need anything here and can + * leave @enable_delay blank. For hwmods that do need a value here, + * to estimate the required value, the best thing to do is to set the + * IP block to run at the slowest interface and functional clock rates + * and the lowest voltages. First, try out a small value, say, 10 + * microseconds, and keep increasing it until the kernel no longer + * crashes. Then add a safety margin to the value that you arrived at + * -- say, 50% -- and specify the value in the structure record + * initializer for @enable_delay as (value + safety_margin). Try not + * to overestimate this number; if @enable_delay is too large, then + * energy will be wasted and the CPU will spin for an unnecessarily + * long time while enabling the device. If @enable_delay is too + * small, the device will trigger an abort. More information is + * available here: + * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg36300.html + * XXX @enable_value will need to be taken into consideration by the + * omap_device code to determine whether the device's current wakeup + * latency constraint can be satisfied if the module is placed into idle. + * + * Parameter names beginning with an underscore are managed internally + * by the omap_hwmod code and should not be set during initialization. */ struct omap_hwmod { const char *name; @@ -484,6 +512,7 @@ struct omap_hwmod { void __iomem *_mpu_rt_va; struct mutex _mutex; struct list_head node; + u16 enable_delay; u16 flags; u8 _mpu_port_index; u8 msuspendmux_reg_id;