From patchwork Sat Oct 12 09:35:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Chen X-Patchwork-Id: 3031031 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 A3BEFBF924 for ; Sat, 12 Oct 2013 09:49:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C4ACA20396 for ; Sat, 12 Oct 2013 09:49:44 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AFFBC2037F for ; Sat, 12 Oct 2013 09:49:43 +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 1VUvol-00013j-Oj; Sat, 12 Oct 2013 09:49:03 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VUvoa-0002Bx-EJ; Sat, 12 Oct 2013 09:48:52 +0000 Received: from mail-db8lp0185.outbound.messaging.microsoft.com ([213.199.154.185] helo=db8outboundpool.messaging.microsoft.com) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VUvoN-00027p-DW for linux-arm-kernel@lists.infradead.org; Sat, 12 Oct 2013 09:48:41 +0000 Received: from mail151-db8-R.bigfish.com (10.174.8.239) by DB8EHSOBE021.bigfish.com (10.174.4.84) with Microsoft SMTP Server id 14.1.225.22; Sat, 12 Oct 2013 09:48:17 +0000 Received: from mail151-db8 (localhost [127.0.0.1]) by mail151-db8-R.bigfish.com (Postfix) with ESMTP id E051822018A; Sat, 12 Oct 2013 09:48:16 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h208ch1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6hzz1de098h1de097h8275bhz2dh2a8h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e23h1fe8h1ff5h1155h) Received: from mail151-db8 (localhost.localdomain [127.0.0.1]) by mail151-db8 (MessageSwitch) id 1381571289615348_19132; Sat, 12 Oct 2013 09:48:09 +0000 (UTC) Received: from DB8EHSMHS002.bigfish.com (unknown [10.174.8.238]) by mail151-db8.bigfish.com (Postfix) with ESMTP id 8740912013C; Sat, 12 Oct 2013 09:48:09 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by DB8EHSMHS002.bigfish.com (10.174.4.12) with Microsoft SMTP Server (TLS) id 14.16.227.3; Sat, 12 Oct 2013 09:48:09 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.3.158.2; Sat, 12 Oct 2013 09:48:07 +0000 Received: from shlinux1.ap.freescale.net (shlinux1.ap.freescale.net [10.192.225.216]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r9C9lllp027790; Sat, 12 Oct 2013 02:48:04 -0700 From: Peter Chen To: , , Subject: [PATCH 04/11] usb: chipidea: add wakeup interrupt handler Date: Sat, 12 Oct 2013 17:35:06 +0800 Message-ID: <1381570513-24927-5-git-send-email-peter.chen@freescale.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1381570513-24927-1-git-send-email-peter.chen@freescale.com> References: <1381570513-24927-1-git-send-email-peter.chen@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131012_054839_794886_F2AD4FF3 X-CRM114-Status: GOOD ( 14.07 ) X-Spam-Score: -1.9 (-) Cc: marex@denx.de, m.grzeschik@pengutronix.de, frank.li@freescale.com, alexander.shishkin@linux.intel.com, linux-usb@vger.kernel.org, peter.chen@freescale.com, kernel@pengutronix.de, festevam@gmail.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.4 required=5.0 tests=BAYES_00,KHOP_BIG_TO_CC, 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 When the controller is at suspend mode, it can be waken up by external events (like vbus, dp/dm or id change). Once we receive the wakeup interrupt, we need to resume the controller first, eg open clocks, disable some wakeup settings, etc. After that, the controller can receive the normal USB interrupts. Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci.h | 1 + drivers/usb/chipidea/core.c | 22 +++++++++++++++++++++- drivers/usb/chipidea/otg.c | 5 +++++ 3 files changed, 27 insertions(+), 1 deletions(-) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index 6c16d11..cc94d17 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -175,6 +175,7 @@ struct ci_hdrc { bool b_sess_valid_event; bool supports_runtime_pm; atomic_t in_lpm; + bool wakeup_int; }; static inline struct ci_role_driver *ci_role(struct ci_hdrc *ci) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 7ffb8cb..d8c245b 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -190,6 +190,13 @@ static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable) * than 1ms) to leave low power mode. */ usleep_range(1500, 2000); + } else if (!enable) { + /* + * At wakeup interrupt, the phcd will be cleared by hardware + * automatically, but the controller needs at least 1ms + * to reflect PHY's status. + */ + usleep_range(1200, 1800); } } @@ -355,6 +362,13 @@ static irqreturn_t ci_irq(int irq, void *data) irqreturn_t ret = IRQ_NONE; u32 otgsc = 0; + if (atomic_read(&ci->in_lpm)) { + disable_irq_nosync(irq); + ci->wakeup_int = true; + pm_runtime_get(ci->dev); + return IRQ_HANDLED; + } + if (ci->is_otg) otgsc = hw_read(ci, OP_OTGSC, ~0); @@ -737,7 +751,13 @@ static int ci_controller_resume(struct device *dev) usb_phy_set_wakeup(ci->transceiver, false); } - atomic_set(&ci->in_lpm, 0); + if (ci->wakeup_int) { + ci->wakeup_int = false; + atomic_set(&ci->in_lpm, 0); + enable_irq(ci->irq); + pm_runtime_put(ci->dev); + } else + atomic_set(&ci->in_lpm, 0); return 0; } diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c index 39bd7ec..54bc7c0 100644 --- a/drivers/usb/chipidea/otg.c +++ b/drivers/usb/chipidea/otg.c @@ -78,10 +78,15 @@ static void ci_otg_work(struct work_struct *work) if (ci->id_event) { ci->id_event = false; + /* Keep controller active during id switch */ + pm_runtime_get_sync(ci->dev); ci_handle_id_switch(ci); + pm_runtime_put_sync(ci->dev); } else if (ci->b_sess_valid_event) { ci->b_sess_valid_event = false; + pm_runtime_get_sync(ci->dev); ci_handle_vbus_change(ci); + pm_runtime_put_sync(ci->dev); } else dev_err(ci->dev, "unexpected event occurs at %s\n", __func__);