]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
usb: dwc2: Fix channel disable flow
authorMinas Harutyunyan <minas.harutyunyan@synopsys.com>
Tue, 5 Mar 2019 11:08:55 +0000 (15:08 +0400)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 3 May 2019 06:13:48 +0000 (09:13 +0300)
Channel disabling/halting should performed for enabled only channels
to avoid warnings "Unable to clear enable on channel N" which seen
if host works in Slave mode.

Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc2/hcd.c

index 7ac7b524243d71b40747fd6f0d972b6d9c661cec..b50ec3714fd8d8bff74110cf36799c1b6f952cf4 100644 (file)
@@ -2247,25 +2247,31 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
                num_channels = hsotg->params.host_channels;
                for (i = 0; i < num_channels; i++) {
                        hcchar = dwc2_readl(hsotg, HCCHAR(i));
-                       hcchar &= ~HCCHAR_CHENA;
-                       hcchar |= HCCHAR_CHDIS;
-                       hcchar &= ~HCCHAR_EPDIR;
-                       dwc2_writel(hsotg, hcchar, HCCHAR(i));
+                       if (hcchar & HCCHAR_CHENA) {
+                               hcchar &= ~HCCHAR_CHENA;
+                               hcchar |= HCCHAR_CHDIS;
+                               hcchar &= ~HCCHAR_EPDIR;
+                               dwc2_writel(hsotg, hcchar, HCCHAR(i));
+                       }
                }
 
                /* Halt all channels to put them into a known state */
                for (i = 0; i < num_channels; i++) {
                        hcchar = dwc2_readl(hsotg, HCCHAR(i));
-                       hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
-                       hcchar &= ~HCCHAR_EPDIR;
-                       dwc2_writel(hsotg, hcchar, HCCHAR(i));
-                       dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
-                               __func__, i);
-
-                       if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i),
-                                                     HCCHAR_CHENA, 1000)) {
-                               dev_warn(hsotg->dev, "Unable to clear enable on channel %d\n",
-                                        i);
+                       if (hcchar & HCCHAR_CHENA) {
+                               hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS;
+                               hcchar &= ~HCCHAR_EPDIR;
+                               dwc2_writel(hsotg, hcchar, HCCHAR(i));
+                               dev_dbg(hsotg->dev, "%s: Halt channel %d\n",
+                                       __func__, i);
+
+                               if (dwc2_hsotg_wait_bit_clear(hsotg, HCCHAR(i),
+                                                             HCCHAR_CHENA,
+                                                             1000)) {
+                                       dev_warn(hsotg->dev,
+                                                "Unable to clear enable on channel %d\n",
+                                                i);
+                               }
                        }
                }
        }