Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935251AbcCPWRi (ORCPT ); Wed, 16 Mar 2016 18:17:38 -0400 Received: from mx1.tlen.pl ([193.222.135.140]:57013 "EHLO mx1.tlen.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934707AbcCPWRg (ORCPT ); Wed, 16 Mar 2016 18:17:36 -0400 From: Przemek Rudy To: johnyoun@synopsys.com Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Przemek Rudy Subject: [PATCH] usb: dwc2: do not override forced dr_mode in gadget setup Date: Wed, 16 Mar 2016 23:10:26 +0100 Message-Id: <1458166226-14983-1-git-send-email-prudy1@o2.pl> X-Mailer: git-send-email 2.5.0 X-WP-MailID: 1fe3ab89618f915dc7635f5760d638ab X-WP-AV: skaner antywirusowy poczty Nowej Poczty X-WP-SPAM: NO 0000000 [gVMk] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2501 Lines: 70 The host/device mode set with dr_mode should be kept all the time, not being changed to OTG in gadget setup (by overriding CFGUSB_FORCEDEVMODE and CFGUSB_FORCEHOSTMODE bits). Signed-off-by: Przemek Rudy --- drivers/usb/dwc2/gadget.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e9940dd..818f158 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2254,6 +2254,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, { u32 intmsk; u32 val; + u32 usbcfg; /* Kill any ep0 requests as controller will be reinitialized */ kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); @@ -2267,10 +2268,16 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, * set configuration. */ + /* keep other bits untouched (so e.g. forced modes are not lost) */ + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | + GUSBCFG_HNPCAP); + /* set the PLL on, remove the HNP/SRP and set the PHY */ val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | - (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | + (val << GUSBCFG_USBTRDTIM_SHIFT); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); dwc2_hsotg_init_fifo(hsotg); @@ -3031,6 +3038,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = { static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) { u32 trdtim; + u32 usbcfg; /* unmask subset of endpoint interrupts */ dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | @@ -3054,11 +3062,16 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) dwc2_hsotg_init_fifo(hsotg); + /* keep other bits untouched (so e.g. forced modes are not lost) */ + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | + GUSBCFG_HNPCAP); + /* set the PLL on, remove the HNP/SRP and set the PHY */ trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | - (trdtim << GUSBCFG_USBTRDTIM_SHIFT), - hsotg->regs + GUSBCFG); + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | + (trdtim << GUSBCFG_USBTRDTIM_SHIFT); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); if (using_dma(hsotg)) __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN); -- 2.5.0