From patchwork Fri Dec 4 02:40:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?Q2h1bmZlbmcgWXVuICjkupHmmKXls7Ap?= X-Patchwork-Id: 7765121 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 42295BEEE1 for ; Fri, 4 Dec 2015 02:43:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5A1BD205B7 for ; Fri, 4 Dec 2015 02:43:34 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 71F1320430 for ; Fri, 4 Dec 2015 02:43:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a4gJD-0006ih-AT; Fri, 04 Dec 2015 02:41:19 +0000 Received: from [210.61.82.184] (helo=mailgw02.mediatek.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a4gJ9-0006fs-QB; Fri, 04 Dec 2015 02:41:16 +0000 X-Listener-Flag: 11101 Received: from mtkhts09.mediatek.inc [(172.21.101.70)] by mailgw02.mediatek.com (envelope-from ) (mhqrelay.mediatek.com ESMTP with TLS) with ESMTP id 245208535; Fri, 04 Dec 2015 10:40:51 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkhts09.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 14.3.181.6; Fri, 4 Dec 2015 10:40:49 +0800 From: Chunfeng Yun To: Mathias Nyman Subject: [PATCH] usb: xhci-mtk: fix AHB bus hang up caused by roothubs polling Date: Fri, 4 Dec 2015 10:40:07 +0800 Message-ID: <1449196807-31785-1-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151203_184116_078036_A9BD3C5B X-CRM114-Status: GOOD ( 13.55 ) X-Spam-Score: -1.1 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sergei Shtylyov , Greg Kroah-Hartman , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Felipe Balbi , Chunfeng Yun , linux-mediatek@lists.infradead.org, Daniel Kurtz , Matthias Brugger , linux-arm-kernel@lists.infradead.org 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 when ip fail to enter sleep mode, register access protection will be disabed, at the same time if all clocks are disabled, access register will hang up AHB bus. the common case causes ip sleep fail is that after all ports enter U3 but before ip enters sleep mode, a port receives a resume signal('K'). this will happens when such as clicks mouse to try to do remote wakeup to stop system enter suspend. so stop polling roothubs to avoid access xHCI register on bus suspend, and restart it when bus resume. Signed-off-by: Chunfeng Yun --- drivers/usb/host/xhci-mtk.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index c9ab6a4..38635fb 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -696,9 +696,24 @@ static int xhci_mtk_remove(struct platform_device *dev) } #ifdef CONFIG_PM_SLEEP +/* + * if ip sleep fail, and all clocks are disabled, access register will hang + * AHB bus, so stop poll roothubs to avoid regs access on bus suspend. + * and no need to check whether ip sleep fail or not; this will cause SPM to + * wakeup system immediately after system suspend complete if ip sleep + * fail, it is what we wanted. + */ static int xhci_mtk_suspend(struct device *dev) { struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + xhci_dbg(xhci, "%s: stop port polling\n", __func__); + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + del_timer_sync(&hcd->rh_timer); + clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); + del_timer_sync(&xhci->shared_hcd->rh_timer); xhci_mtk_host_disable(mtk); xhci_mtk_phy_power_off(mtk); @@ -710,11 +725,19 @@ static int xhci_mtk_suspend(struct device *dev) static int xhci_mtk_resume(struct device *dev) { struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); usb_wakeup_disable(mtk); xhci_mtk_clks_enable(mtk); xhci_mtk_phy_power_on(mtk); xhci_mtk_host_enable(mtk); + + xhci_dbg(xhci, "%s: restart port polling\n", __func__); + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + usb_hcd_poll_rh_status(hcd); + set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); + usb_hcd_poll_rh_status(xhci->shared_hcd); return 0; }