usb: dwc3: gadget: Check for disabled LPM quirk
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>
Wed, 14 Apr 2021 02:13:18 +0000 (19:13 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Apr 2021 13:58:33 +0000 (15:58 +0200)
If the device doesn't support LPM, make sure to disable the LPM
capability and don't advertise to the host that it supports it.

Acked-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/9e68527ff932b1646f92a7593d4092a903754666.1618366071.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index 2022d90..5c25e6a 100644 (file)
@@ -1286,6 +1286,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
                                "snps,usb3_lpm_capable");
        dwc->usb2_lpm_disable = device_property_read_bool(dev,
                                "snps,usb2-lpm-disable");
+       dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev,
+                               "snps,usb2-gadget-lpm-disable");
        device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
                                &rx_thr_num_pkt_prd);
        device_property_read_u8(dev, "snps,rx-max-burst-prd",
index 5a9b56b..695ff2d 100644 (file)
@@ -1036,7 +1036,8 @@ struct dwc3_scratchpad_array {
  * @dis_start_transfer_quirk: set if start_transfer failure SW workaround is
  *                     not needed for DWC_usb31 version 1.70a-ea06 and below
  * @usb3_lpm_capable: set if hadrware supports Link Power Management
- * @usb2_lpm_disable: set to disable usb2 lpm
+ * @usb2_lpm_disable: set to disable usb2 lpm for host
+ * @usb2_gadget_lpm_disable: set to disable usb2 lpm for gadget
  * @disable_scramble_quirk: set if we enable the disable scramble quirk
  * @u2exit_lfps_quirk: set if we enable u2exit lfps quirk
  * @u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk
@@ -1242,6 +1243,7 @@ struct dwc3 {
        unsigned                dis_start_transfer_quirk:1;
        unsigned                usb3_lpm_capable:1;
        unsigned                usb2_lpm_disable:1;
+       unsigned                usb2_gadget_lpm_disable:1;
 
        unsigned                disable_scramble_quirk:1;
        unsigned                u2exit_lfps_quirk:1;
index ec7aabb..6227641 100644 (file)
@@ -3495,6 +3495,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
        /* Enable USB2 LPM Capability */
 
        if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) &&
+           !dwc->usb2_gadget_lpm_disable &&
            (speed != DWC3_DSTS_SUPERSPEED) &&
            (speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
                reg = dwc3_readl(dwc->regs, DWC3_DCFG);
@@ -3521,6 +3522,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 
                dwc3_gadget_dctl_write_safe(dwc, reg);
        } else {
+               if (dwc->usb2_gadget_lpm_disable) {
+                       reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+                       reg &= ~DWC3_DCFG_LPM_CAP;
+                       dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+               }
+
                reg = dwc3_readl(dwc->regs, DWC3_DCTL);
                reg &= ~DWC3_DCTL_HIRD_THRES_MASK;
                dwc3_gadget_dctl_write_safe(dwc, reg);
@@ -3969,7 +3976,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
        dwc->gadget->ssp_rate           = USB_SSP_GEN_UNKNOWN;
        dwc->gadget->sg_supported       = true;
        dwc->gadget->name               = "dwc3-gadget";
-       dwc->gadget->lpm_capable        = true;
+       dwc->gadget->lpm_capable        = !dwc->usb2_gadget_lpm_disable;
 
        /*
         * FIXME We might be setting max_speed to <SUPER, however versions