From patchwork Tue Feb 24 03:40:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 5869481 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 34D5FBF440 for ; Tue, 24 Feb 2015 03:43:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3D94F200E0 for ; Tue, 24 Feb 2015 03:43:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F3DE4200B4 for ; Tue, 24 Feb 2015 03:43:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752309AbbBXDmL (ORCPT ); Mon, 23 Feb 2015 22:42:11 -0500 Received: from cantor2.suse.de ([195.135.220.15]:60585 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752264AbbBXDmI (ORCPT ); Mon, 23 Feb 2015 22:42:08 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "Cc" Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 79A52ABB1; Tue, 24 Feb 2015 03:42:07 +0000 (UTC) From: NeilBrown To: Tony Lindgren , Felipe Balbi , Kishon Vijay Abraham I Date: Tue, 24 Feb 2015 14:40:37 +1100 Subject: [PATCH 1/4] usb: phy: twl4030: make runtime pm more reliable. Cc: linux-omap@vger.kernel.org, lkml Cc: GTA04 owners Message-ID: <20150224034036.31400.6133.stgit@notabene.brown> In-Reply-To: <20150224033730.31400.78200.stgit@notabene.brown> References: <20150224033730.31400.78200.stgit@notabene.brown> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 A construct like: if (pm_runtime_suspended(twl->dev)) pm_runtime_get_sync(twl->dev); is against the spirit of the runtime_pm interface as it makes the internal refcounting useless. In this case it is also racy, particularly as 'put_autosuspend' is use to drop a reference. When that happens a timer is started and the device is runtime-suspended after the timeout. If the above code runs in this window, the device will not be found to be suspended so no pm_runtime reference is taken. When the timer expires the device will be suspended, which is against the intention of the code. So be more direct is taking and dropping references. If twl->linkstat is VBUS_VALID or ID_GROUND, then hold a pm_runtime reference, otherwise don't. Signed-off-by: NeilBrown Tested-by: Tony Lindgren --- drivers/phy/phy-twl4030-usb.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 8e87f54671f3..97c59074233f 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -536,8 +536,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) mutex_lock(&twl->lock); if (status >= 0 && status != twl->linkstat) { + status_changed = + (twl->linkstat == OMAP_MUSB_VBUS_VALID || + twl->linkstat == OMAP_MUSB_ID_GROUND) + != + (status == OMAP_MUSB_VBUS_VALID || + status == OMAP_MUSB_ID_GROUND); twl->linkstat = status; - status_changed = true; } mutex_unlock(&twl->lock); @@ -555,13 +560,10 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) */ if ((status == OMAP_MUSB_VBUS_VALID) || (status == OMAP_MUSB_ID_GROUND)) { - if (pm_runtime_suspended(twl->dev)) - pm_runtime_get_sync(twl->dev); + pm_runtime_get_sync(twl->dev); } else { - if (pm_runtime_active(twl->dev)) { - pm_runtime_mark_last_busy(twl->dev); - pm_runtime_put_autosuspend(twl->dev); - } + pm_runtime_mark_last_busy(twl->dev); + pm_runtime_put_autosuspend(twl->dev); } omap_musb_mailbox(status); } @@ -768,6 +770,10 @@ static int twl4030_usb_remove(struct platform_device *pdev) /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); + + if (twl->linkstat == OMAP_MUSB_VBUS_VALID || + twl->linkstat == OMAP_MUSB_ID_GROUND) + pm_runtime_put_noidle(twl->dev); pm_runtime_mark_last_busy(twl->dev); pm_runtime_put(twl->dev);