From patchwork Mon Dec 9 01:32:54 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 3307991 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 66061C0D4A for ; Mon, 9 Dec 2013 01:33:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 567B62022A for ; Mon, 9 Dec 2013 01:33:32 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9D6CF20221 for ; Mon, 9 Dec 2013 01:33:26 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vppis-00047Q-BR; Mon, 09 Dec 2013 01:33:22 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vppip-0000hx-T2; Mon, 09 Dec 2013 01:33:19 +0000 Received: from utopia.booyaka.com ([74.50.51.50]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vppim-0000hd-UU for linux-arm-kernel@lists.infradead.org; Mon, 09 Dec 2013 01:33:17 +0000 Received: (qmail 8112 invoked by uid 1019); 9 Dec 2013 01:32:54 -0000 Date: Mon, 9 Dec 2013 01:32:54 +0000 (UTC) From: Paul Walmsley To: Roger Quadros Subject: Re: [PATCH 2/3] ARM: OMAP2+: hwmod: Fix RESET logic In-Reply-To: <1386080748-17005-3-git-send-email-rogerq@ti.com> Message-ID: References: <1386080748-17005-1-git-send-email-rogerq@ti.com> <1386080748-17005-3-git-send-email-rogerq@ti.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131208_203317_208101_4AE026DE X-CRM114-Status: GOOD ( 19.35 ) X-Spam-Score: -1.9 (-) Cc: sr@denx.de, michael@amarulasolutions.com, tony@atomide.com, bigeasy@linutronix.de, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, balbi@ti.com, linux-omap@vger.kernel.org, tomi.valkeinen@ti.com, bcousson@baylibre.com, David.Laight@ACULAB.COM, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Roger, On Tue, 3 Dec 2013, Roger Quadros wrote: > In _ocp_softreset(), after _set_softreset() + write_sysconfig(), > the hwmod's sysc_cache will always contain SOFTRESET bit set > so all further writes to sysconfig using this cache will initiate > a repeated SOFTRESET e.g. enable_sysc(). This is true for OMAP3 like > platforms that have RESET_DONE status in the SYSSTATUS register and > so the the SOFTRESET bit in SYSCONFIG is not automatically cleared. > It is not a problem for OMAP4 like platforms that indicate RESET > completion by clearing the SOFTRESET bit in the SYSCONFIG register. > > This repeated SOFTRESET is undesired and was the root cause of > USB host issues on OMAP3 platforms when hwmod was allowed to do the > SOFTRESET for the USB Host module. Doh :-( Nice catch. Renamed _clr_softreset() to _clear_softreset() and queued the following for v3.13-rc. - Paul From: Roger Quadros ARM: OMAP2+: hwmod: Fix SOFTRESET logic In _ocp_softreset(), after _set_softreset() + write_sysconfig(), the hwmod's sysc_cache will always contain SOFTRESET bit set so all further writes to sysconfig using this cache will initiate a repeated SOFTRESET e.g. enable_sysc(). This is true for OMAP3 like platforms that have RESET_DONE status in the SYSSTATUS register and so the the SOFTRESET bit in SYSCONFIG is not automatically cleared. It is not a problem for OMAP4 like platforms that indicate RESET completion by clearing the SOFTRESET bit in the SYSCONFIG register. This repeated SOFTRESET is undesired and was the root cause of USB host issues on OMAP3 platforms when hwmod was allowed to do the SOFTRESET for the USB Host module. To fix this we clear the SOFTRESET bit and update the sysconfig register + sysc_cache using write_sysconfig(). Signed-off-by: Roger Quadros [paul@pwsan.com: renamed _clr_softreset() to _clear_softreset()] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index e3f0ecaf87dd..cacc0c7e8634 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -399,7 +399,7 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) } /** - * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v + * _set_softreset: set OCP_SYSCONFIG.SOFTRESET bit in @v * @oh: struct omap_hwmod * * @v: pointer to register contents to modify * @@ -427,6 +427,36 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) } /** + * _clear_softreset: clear OCP_SYSCONFIG.SOFTRESET bit in @v + * @oh: struct omap_hwmod * + * @v: pointer to register contents to modify + * + * Clear the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon + * error or 0 upon success. + */ +static int _clear_softreset(struct omap_hwmod *oh, u32 *v) +{ + u32 softrst_mask; + + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET)) + return -EINVAL; + + if (!oh->class->sysc->sysc_fields) { + WARN(1, + "omap_hwmod: %s: sysc_fields absent for sysconfig class\n", + oh->name); + return -EINVAL; + } + + softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); + + *v &= ~softrst_mask; + + return 0; +} + +/** * _wait_softreset_complete - wait for an OCP softreset to complete * @oh: struct omap_hwmod * to wait on * @@ -1911,6 +1941,12 @@ static int _ocp_softreset(struct omap_hwmod *oh) ret = _set_softreset(oh, &v); if (ret) goto dis_opt_clks; + + _write_sysconfig(v, oh); + ret = _clear_softreset(oh, &v); + if (ret) + goto dis_opt_clks; + _write_sysconfig(v, oh); if (oh->class->sysc->srst_udelay) @@ -3169,6 +3205,11 @@ int omap_hwmod_softreset(struct omap_hwmod *oh) goto error; _write_sysconfig(v, oh); + ret = _clear_softreset(oh, &v); + if (ret) + goto error; + _write_sysconfig(v, oh); + error: return ret; }