usb: dwc_otg_310: add force host channel halt quirk

According to DWC2 Programming Guide, if a host channel is
used for non-split periodic transfer, we must not disable
the channel if we want to halt it, and at the end of the
next uframe/frame (in the worst case), the core generates
a channel halted and disables the channel automatically.

But some specil usb device, like usb audio (VID = 0x0572,
PID = 0x1494, Manufacturer: Conexant Systems INC), we
need to halt the channel immediately when do close usb
audio operation. Otherwise, the host may still start a
new transaction after usb audio close, and cause to set
usb interface failed when open usb audio next time.

This patch introduces a new quirk to force host channel
halt even if it's used for a non-split periodic transfer.

Change-Id: I2911ad8f68bb3738691ac683b0b64330d3428213
Signed-off-by: Wu Liang feng <wulf@rock-chips.com>
This commit is contained in:
Wu Liang feng 2017-09-08 16:30:06 +08:00 committed by Tao Huang
parent 8a68b9361b
commit 41ebd2ae40
4 changed files with 14 additions and 1 deletions

View File

@ -21,6 +21,8 @@ Required properties:
Optional properties:
- rockchip,usb-pmic-vbus: If present, OTG VBUS 5V is supplied
from PMIC.
- rockchip,hc-halt-quirk: when set, force to halt a host channel
even if it's used for a non-split periodic transfer.
Example:
- RK3288

View File

@ -2856,7 +2856,7 @@ void dwc_otg_hc_halt(dwc_otg_core_if_t *core_if,
hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
if ((hcchar.b.chen == 0) ||
(!hc->do_split &&
(!hc->do_split && !core_if->hc_halt_quirk &&
((hc->ep_type == DWC_OTG_EP_TYPE_ISOC) ||
(hc->ep_type == DWC_OTG_EP_TYPE_INTR)))) {
/*

View File

@ -849,6 +849,9 @@ struct dwc_otg_core_if {
#define USB_MODE_FORCE_HOST (1)
#define USB_MODE_FORCE_DEVICE (2)
/* Indicates need to force a host channel halt */
bool hc_halt_quirk;
/* Indicate USB get VBUS 5V from PMIC(e.g. rk81x) */
bool pmic_vbus;

View File

@ -1105,6 +1105,10 @@ static int host20_driver_probe(struct platform_device *_dev)
dwc_otg_device->common_irq_installed = 1;
}
/* Indicates need to force a host channel halt */
dwc_otg_device->core_if->hc_halt_quirk =
of_property_read_bool(node, "rockchip,hc-halt-quirk");
/*
* Initialize the DWC_otg core.
* In order to reduce the time of initialization,
@ -1516,6 +1520,10 @@ static int otg20_driver_probe(struct platform_device *_dev)
dwc_otg_device->core_if->pmic_vbus = of_property_read_bool(node,
"rockchip,usb-pmic-vbus");
/* Indicates need to force a host channel halt */
dwc_otg_device->core_if->hc_halt_quirk =
of_property_read_bool(node, "rockchip,hc-halt-quirk");
#ifndef DWC_HOST_ONLY
/*
* Initialize the PCD