diff --git a/arch/arm/boot/dts/overlays/dwc2-overlay.dts b/arch/arm/boot/dts/overlays/dwc2-overlay.dts index 90c981143fc7a5..527abc9f0ddf71 100644 --- a/arch/arm/boot/dts/overlays/dwc2-overlay.dts +++ b/arch/arm/boot/dts/overlays/dwc2-overlay.dts @@ -8,7 +8,7 @@ target = <&usb>; #address-cells = <1>; #size-cells = <1>; - __overlay__ { + dwc2_usb: __overlay__ { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>; @@ -21,9 +21,9 @@ }; __overrides__ { - dr_mode = <&usb>, "dr_mode"; - g-np-tx-fifo-size = <&usb>,"g-np-tx-fifo-size:0"; - g-rx-fifo-size = <&usb>,"g-rx-fifo-size:0"; - g-tx-fifo-size = <&usb>,"g-tx-fifo-size:0"; + dr_mode = <&dwc2_usb>, "dr_mode"; + g-np-tx-fifo-size = <&dwc2_usb>,"g-np-tx-fifo-size:0"; + g-rx-fifo-size = <&dwc2_usb>,"g-rx-fifo-size:0"; + g-tx-fifo-size = <&dwc2_usb>,"g-tx-fifo-size:0"; }; }; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 422ab7da4eb51b..da91964bf67eb9 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);