diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 2ef7ffdc61df..1f0ce784fc01 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1016,6 +1016,8 @@ static int dwc3_probe(struct platform_device *pdev) "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 c025c3c007bc..10a32444a6db 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -821,6 +821,7 @@ struct dwc3_scratchpad_array { * @dis_u3_autosuspend_quirk: set if the we disable usb3 autosuspend * @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_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists @@ -980,6 +981,7 @@ struct dwc3 { unsigned dis_u3_autosuspend_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 257c725e5d7a..302e54ba223d 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -431,7 +431,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, 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; @@ -445,7 +445,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, 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; @@ -592,7 +592,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;