diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index d6899567a0fa..79b789444fee 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1275,6 +1275,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,dis_u3_susphy_quirk"); dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); + dwc->dis_u1u2_quirk = device_property_read_bool(dev, + "snps,dis-u1u2-quirk"); dwc->dis_enblslpm_quirk = device_property_read_bool(dev, "snps,dis_enblslpm_quirk"); dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 9a023769cba1..232ccd02a775 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -981,6 +981,7 @@ struct dwc3_scratchpad_array { * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy + * @dis_u1u2_quirk: set if we reject transition to U1 or U2 state * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG, * disabling the suspend signal to the PHY. * @dis_rxdet_inp3_quirk: set if we disable Rx.Detect in P3 @@ -1160,6 +1161,7 @@ struct dwc3 { unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; unsigned dis_u2_susphy_quirk:1; + unsigned dis_u1u2_quirk:1; unsigned dis_enblslpm_quirk:1; unsigned dis_rxdet_inp3_quirk:1; unsigned dis_u2_freeclk_exists_quirk:1; diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 8efde178eef4..26b0aa3fa778 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -381,7 +381,7 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, return -EINVAL; reg = dwc3_readl(dwc->regs, DWC3_DCTL); - if (set) + if (set && !dwc->dis_u1u2_quirk) reg |= DWC3_DCTL_INITU1ENA; else reg &= ~DWC3_DCTL_INITU1ENA; @@ -403,7 +403,7 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, return -EINVAL; reg = dwc3_readl(dwc->regs, DWC3_DCTL); - if (set) + if (set && !dwc->dis_u1u2_quirk) reg |= DWC3_DCTL_INITU2ENA; else reg &= ~DWC3_DCTL_INITU2ENA; @@ -626,7 +626,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) * nothing is pending from application. */ reg = dwc3_readl(dwc->regs, DWC3_DCTL); - reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); + if (dwc->dis_u1u2_quirk) + reg &= ~(DWC3_DCTL_ACCEPTU1ENA | + DWC3_DCTL_ACCEPTU2ENA); + else + reg |= (DWC3_DCTL_ACCEPTU1ENA | + DWC3_DCTL_ACCEPTU2ENA); dwc3_writel(dwc->regs, DWC3_DCTL, reg); } break;