From patchwork Fri Nov 21 14:14:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 41320 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3E7212452C for ; Fri, 21 Nov 2014 14:15:09 +0000 (UTC) Received: by mail-la0-f70.google.com with SMTP id q1sf3106797lam.9 for ; Fri, 21 Nov 2014 06:15:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=++QogRGoKEoo2dc72lPJKsKSafAAu7Ihp6OFJiJV8qg=; b=LzbC5pr8RaQgavzpMXvscwlnUf5msuS9uZrndDu1IywTPJlnlTdImmpwIc4U15vCsa AhO6PxyRpTyxyI6Tzew0lP4ZjqleGCXJYdoMxvUeiLu7vSgzMBTWhIH0cMvunmB17Evg vBLnMBscB8N1TeTi7/ChY7nCCUDJfb/8IODxibaeoD5Z8mQfGMTnocdcn+kIdPKnANrs buJ/QH34zpn05pLg/07TSj2jvlHAeTxd29g5MURb+eYa2SWQbmSnALK9IiS1DDvXC2Tw BNBpTOsIw+s7hYHFzNCfC+kfAmZ3rE1NrMWQ8m/p1MO7RinKLSEYf105xgFDIyabEoz2 9ItQ== X-Gm-Message-State: ALoCoQnICM722NokNcwPwBcs8xzm65O061yHfJptK4kwrmfIGsj4BeUBsbQe9PSMtktx4Pr5VA2n X-Received: by 10.181.12.37 with SMTP id en5mr11139896wid.6.1416579304187; Fri, 21 Nov 2014 06:15:04 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.121.72 with SMTP id li8ls215801lab.101.gmail; Fri, 21 Nov 2014 06:15:03 -0800 (PST) X-Received: by 10.152.6.228 with SMTP id e4mr4852986laa.71.1416579303624; Fri, 21 Nov 2014 06:15:03 -0800 (PST) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id q5si5526708lbp.93.2014.11.21.06.15.03 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 21 Nov 2014 06:15:03 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by mail-la0-f49.google.com with SMTP id hs14so4267219lab.36 for ; Fri, 21 Nov 2014 06:15:02 -0800 (PST) X-Received: by 10.152.43.79 with SMTP id u15mr1134660lal.29.1416579302280; Fri, 21 Nov 2014 06:15:02 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp97764lbc; Fri, 21 Nov 2014 06:15:01 -0800 (PST) X-Received: by 10.70.35.207 with SMTP id k15mr7454446pdj.166.1416579300359; Fri, 21 Nov 2014 06:15:00 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id qe5si8906981pdb.2.2014.11.21.06.14.59 for ; Fri, 21 Nov 2014 06:15:00 -0800 (PST) Received-SPF: none (google.com: linux-samsung-soc-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755321AbaKUOO6 (ORCPT + 4 others); Fri, 21 Nov 2014 09:14:58 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:15284 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751175AbaKUOO6 (ORCPT ); Fri, 21 Nov 2014 09:14:58 -0500 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NFE004ML7POIO30@mailout1.w1.samsung.com>; Fri, 21 Nov 2014 14:17:49 +0000 (GMT) X-AuditID: cbfec7f5-b7f956d000005ed7-41-546f48df97a8 Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id AD.FC.24279.FD84F645; Fri, 21 Nov 2014 14:14:55 +0000 (GMT) Received: from amdc1339.digital.local ([106.116.147.30]) by eusync1.samsung.com (Oracle Communications Messaging Server 7u4-23.01 (7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NFE00CB17KQS570@eusync1.samsung.com>; Fri, 21 Nov 2014 14:14:55 +0000 (GMT) From: Marek Szyprowski To: linux-usb@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: Marek Szyprowski , Kyungmin Park , Robert Baldyga , Paul Zimmerman , Krzysztof Kozlowski , Felipe Balbi Subject: [PATCH v6 1/3] usb: dwc2/gadget: rework disconnect event handling Date: Fri, 21 Nov 2014 15:14:47 +0100 Message-id: <1416579289-31939-1-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrDJMWRmVeSWpSXmKPExsVy+t/xy7r3PfJDDFb84bA4eL/e4vULQ4uz TW/YLWac38dksWhZK7PF2iN32S22T5nOZPHg8E52Bw6Pvi2rGD227P/M6HH8xnYmj8+b5AJY orhsUlJzMstSi/TtErgyXnzsYy/4plIx8+FatgbG93JdjJwcEgImEp3/57BA2GISF+6tZ+ti 5OIQEljKKHF//xVWCKePSeLO3q9MIFVsAoYSXW+72EBsEQEHiSVL74DZzAI/GSUu/eADsYUF vCQ+Xj8DVs8ioCrxcMsydhCbV8BD4uDvP0wQ2+Qk/r9cwTSBkXsBI8MqRtHU0uSC4qT0XCO9 4sTc4tK8dL3k/NxNjJAQ+bqDcekxq0OMAhyMSjy8F2blhgixJpYVV+YeYpTgYFYS4S0Xzg8R 4k1JrKxKLcqPLyrNSS0+xMjEwSnVwGiZzN2tq7L+vIZ480Wv/FUFl6usp/IwHastmLIi1Mdi 7YJ0ia9ukuyHorKWL34UxRe53F3u84eDuV6vTMpW15rNdKxh+SlwTVfOW6CRddNr74Lya6HP /Co+r1k55W3Lqz1rbXJM/H5+5kr9KJa3VSHe0i1F2vdMUMKZbCnb48xyqzeyadlvV2Ipzkg0 1GIuKk4EAIyHwDbvAQAA Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: m.szyprowski@samsung.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds a call to s3c_hsotg_disconnect() from 'end session' interrupt (GOTGINT_SES_END_DET) to correctly notify gadget subsystem about unplugged usb cable. DISCONNINT interrupt cannot be used for this purpose, because it is asserted only in host mode. To avoid reporting disconnect event more than once, a disconnect call has been moved from USB_REQ_SET_ADDRESS handling function to SESSREQINT interrupt. This way driver ensures that disconnect event is reported either when usb cable is unplugged or every time the host starts a new session. To handle devices which has been synthesized without SRP support, connected state is set in ENUMDONE interrupt. Signed-off-by: Marek Szyprowski Acked-by: Paul Zimmerman --- drivers/usb/dwc2/core.h | 3 +++ drivers/usb/dwc2/core_intr.c | 9 +++++++++ drivers/usb/dwc2/gadget.c | 10 +++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 4710935fbad3..2cb0ac31ae86 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -687,6 +687,7 @@ struct dwc2_hsotg { u8 ctrl_buff[8]; struct usb_gadget gadget; + unsigned int connected:1; unsigned int setup; unsigned long last_rst; struct s3c_hsotg_ep *eps; @@ -968,6 +969,7 @@ extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2); extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); +extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); #else static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } @@ -979,6 +981,7 @@ static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2) {} static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} +static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} #endif #if IS_ENABLED(CONFIG_USB_DWC2_HOST) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index b176c2fc34e5..ad43c5bc1ef1 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -128,6 +128,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dwc2_op_state_str(hsotg)); gotgctl = readl(hsotg->regs + GOTGCTL); + if (dwc2_is_device_mode(hsotg)) + s3c_hsotg_disconnect(hsotg); + if (hsotg->op_state == OTG_STATE_B_HOST) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; } else { @@ -314,6 +317,12 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) /* Clear interrupt */ writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); + + /* + * Report disconnect if there is any previous session established + */ + if (dwc2_is_device_mode(hsotg)) + s3c_hsotg_disconnect(hsotg); } /* diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 685527b58bde..c0673ad4c4ad 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1030,7 +1030,6 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, } static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); -static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg); /** * s3c_hsotg_stall_ep0 - stall ep0 @@ -1108,7 +1107,6 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { switch (ctrl->bRequest) { case USB_REQ_SET_ADDRESS: - s3c_hsotg_disconnect(hsotg); dcfg = readl(hsotg->regs + DCFG); dcfg &= ~DCFG_DEVADDR_MASK; dcfg |= (le16_to_cpu(ctrl->wValue) << @@ -2028,15 +2026,20 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, * transactions and signal the gadget driver that this * has happened. */ -static void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) +void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) { unsigned ep; + if (!hsotg->connected) + return; + + hsotg->connected = 0; for (ep = 0; ep < hsotg->num_of_eps; ep++) kill_all_requests(hsotg, &hsotg->eps[ep], -ESHUTDOWN, true); call_gadget(hsotg, disconnect); } +EXPORT_SYMBOL_GPL(s3c_hsotg_disconnect); /** * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler @@ -2289,6 +2292,7 @@ irq_retry: writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); s3c_hsotg_irq_enumdone(hsotg); + hsotg->connected = 1; } if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) {