diff options
author | Minas Harutyunyan <minas.harutyunyan@synopsys.com> | 2019-03-05 15:08:55 +0400 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2019-05-03 09:13:48 +0300 |
commit | 5799aecd64f2bb6c8175a2e86fbcb9e60d052221 (patch) | |
tree | bc53400e05489d36f1ddf7d65dcc65d4d08f90b8 /drivers/usb/dwc2 | |
parent | c8006f67ae0371900e601112d9f9cd8fff1c8387 (diff) | |
download | linux-5799aecd64f2bb6c8175a2e86fbcb9e60d052221.tar.bz2 |
usb: dwc2: Fix channel disable flow
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>
Diffstat (limited to 'drivers/usb/dwc2')
-rw-r--r-- | drivers/usb/dwc2/hcd.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 7ac7b524243d..b50ec3714fd8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -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); + } } } } |