From patchwork Sat May 5 13:46:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 10382159 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id ABCE46053F for ; Sat, 5 May 2018 13:46:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CE9B28249 for ; Sat, 5 May 2018 13:46:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8077229128; Sat, 5 May 2018 13:46:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B102428249 for ; Sat, 5 May 2018 13:46:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751183AbeEENq1 (ORCPT ); Sat, 5 May 2018 09:46:27 -0400 Received: from smtprelay.synopsys.com ([198.182.37.59]:48545 "EHLO smtprelay.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750967AbeEENq1 (ORCPT ); Sat, 5 May 2018 09:46:27 -0400 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id 738641E149E for ; Sat, 5 May 2018 15:46:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1525527985; bh=3nYn7GdV925uTv1/X/47SLlM5F3PNT5JWGSEIGKZhp8=; h=Date:From:Subject:To:CC:From; b=jJVTipoxTAg3MpPL01BdhZHxXPqpXHUGEUdTFjLzuwfyzDbCKEuwuxrJLasEhH2eS UuKwQlu5PGniQK9QCZ0Ph8j4rlI6NzwwbQTo4PsQgj8N10bBl+pzln4eLydFls3dOl OMuZQ3BHJ+eEB0qiVaf5p606s6sV1WBY0dhyrxjrzWmfLLbh6jOgW/d/98K7tcijl3 J9Kyv34Vfe4MAUM34uCatRBI83PkhOZrFDJRpau+uMozpYv4B/QmAmOw57wpWxFd9+ CBircieiYpcajuTL6Q5Q8COPDVFu0KnFp7zuqJxXzNKh1fWSInjs6oQWAxG7B3pmmN c73b1FHvmvneQ== Received: from US01WXQAHTC1.internal.synopsys.com (us01wxqahtc1.internal.synopsys.com [10.12.238.230]) by mailhost.synopsys.com (Postfix) with ESMTP id CE2D231B2; Sat, 5 May 2018 06:46:24 -0700 (PDT) Received: from US01WEHTC1.internal.synopsys.com (10.12.239.236) by US01WXQAHTC1.internal.synopsys.com (10.12.238.230) with Microsoft SMTP Server (TLS) id 14.3.361.1; Sat, 5 May 2018 06:46:24 -0700 Received: from arturp-ubuntu (10.13.184.20) by us01wehtc1.internal.synopsys.com (10.12.239.236) with Microsoft SMTP Server (TLS) id 14.3.361.1; Sat, 5 May 2018 06:46:23 -0700 Received: by arturp-ubuntu (sSMTP sendmail emulation); Sat, 05 May 2018 09:46:26 -0400 Date: Sat, 5 May 2018 09:46:26 -0400 Message-ID: From: Artur Petrosyan Subject: [PATCH] usb: dwc2: Change reading of current frame number flow. To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , CC: John Youn , Artur Petrosyan MIME-Version: 1.0 X-Originating-IP: [10.13.184.20] Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The current frame_number is read from core for both device and host modes. Reading of the current frame number needs to be performed ASAP due to IRQ latency's. This is why, it is moved to common interrupt handler. Accordingly updated dwc2_gadget_target_frame_elapsed() function which uses stored frame_number instead of reading frame number. In cases when target frame value is incremented the frame_number is required to read again. Signed-off-by: Artur Petrosyan Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/core.h | 7 ++++--- drivers/usb/dwc2/core_intr.c | 8 ++++++++ drivers/usb/dwc2/gadget.c | 13 +++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d83be5651f87..a435db4fe948 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -813,6 +813,9 @@ struct dwc2_hregs_backup { * @gadget_enabled Peripheral mode sub-driver initialization indicator. * @ll_hw_enabled Status of low-level hardware resources. * @hibernated: True if core is hibernated + * @frame_number: Frame number read from the core. For both device + * and host modes. The value ranges are from 0 + * to HFNUM_MAX_FRNUM. * @phy: The otg phy transceiver structure for phy control. * @uphy: The otg phy transceiver structure for old USB phy * control. @@ -886,8 +889,6 @@ struct dwc2_hregs_backup { * @hs_periodic_bitmap: Bitmap used by the microframe scheduler any time the * host is in high speed mode; low speed schedules are * stored elsewhere since we need one per TT. - * @frame_number: Frame number read from the core at SOF. The value ranges - * from 0 to HFNUM_MAX_FRNUM. * @periodic_qh_count: Count of periodic QHs, if using several eps. Used for * SOF enable/disable. * @free_hc_list: Free host channels in the controller. This is a list of @@ -954,6 +955,7 @@ struct dwc2_hsotg { unsigned int gadget_enabled:1; unsigned int ll_hw_enabled:1; unsigned int hibernated:1; + u16 frame_number; struct phy *phy; struct usb_phy *uphy; @@ -1027,7 +1029,6 @@ struct dwc2_hsotg { u16 periodic_usecs; unsigned long hs_periodic_bitmap[ DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)]; - u16 frame_number; u16 periodic_qh_count; bool bus_suspended; bool new_connection; diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 2982a155734d..cc90b58b6b3c 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -778,6 +778,14 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) goto out; } + /* Reading current frame number value in device or host modes. */ + if (dwc2_is_device_mode(hsotg)) + hsotg->frame_number = (dwc2_readl(hsotg->regs + DSTS) + & DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT; + else + hsotg->frame_number = (dwc2_readl(hsotg->regs + HFNUM) + & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT; + gintsts = dwc2_read_common_intr(hsotg); if (gintsts & ~GINTSTS_PRTINT) retval = IRQ_HANDLED; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6c32bf26e48e..f7343cda3234 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1235,7 +1235,7 @@ static bool dwc2_gadget_target_frame_elapsed(struct dwc2_hsotg_ep *hs_ep) { struct dwc2_hsotg *hsotg = hs_ep->parent; u32 target_frame = hs_ep->target_frame; - u32 current_frame = dwc2_hsotg_read_frameno(hsotg); + u32 current_frame = hsotg->frame_number; bool frame_overrun = hs_ep->frame_overrun; if (!frame_overrun && current_frame >= target_frame) @@ -1350,8 +1350,15 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, return 0; } - while (dwc2_gadget_target_frame_elapsed(hs_ep)) + /* Update current frame number value. */ + hs->frame_number = dwc2_hsotg_read_frameno(hs); + while (dwc2_gadget_target_frame_elapsed(hs_ep)) { dwc2_gadget_incr_frame_num(hs_ep); + /* Update current frame number value once more as it + * changes here. + */ + hs->frame_number = dwc2_hsotg_read_frameno(hs); + } if (hs_ep->target_frame != TARGET_FRAME_INITIAL) dwc2_hsotg_start_req(hs, hs_ep, hs_req, false); @@ -2731,6 +2738,8 @@ static void dwc2_gadget_handle_ep_disabled(struct dwc2_hsotg_ep *hs_ep) dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, -ENODATA); dwc2_gadget_incr_frame_num(hs_ep); + /* Update current frame number value. */ + hsotg->frame_number = dwc2_hsotg_read_frameno(hsotg); } while (dwc2_gadget_target_frame_elapsed(hs_ep)); dwc2_gadget_start_next_request(hs_ep);